在2017年用IBDesignable绘制虚线(而不是虚线)
用UIKit绘制虚线很容易。 所以:
CGFloat dashes[] = {4, 2}; [path setLineDash:dashes count:2 phase:0]; [path stroke];
有没有办法绘制一条真正的虚线?
有任何想法吗?
由于这个问题是真的老了,没有人提出了一个完整的@IBDesignable
解决scheme,这里是…
希望它可以帮助某些人打字。
@IBDesignable class DottedVertical: UIView { @IBInspectable var dotColor: UIColor = UIColor.etc @IBInspectable var lowerHalfOnly: Bool = false override func draw(_ rect: CGRect) { // say you want 8 dots, with perfect fenceposting: let totalCount = 8 + 8 - 1 let fullHeight = bounds.size.height let width = bounds.size.width let itemLength = fullHeight / CGFloat(totalCount) let path = UIBezierPath() let beginFromTop = CGFloat(0.0) let top = CGPoint(x: width/2, y: beginFromTop) let bottom = CGPoint(x: width/2, y: fullHeight) path.move(to: top) path.addLine(to: bottom) path.lineWidth = width let dashes: [CGFloat] = [itemLength, itemLength] path.setLineDash(dashes, count: dashes.count, phase: 0) // for ROUNDED dots, simply change to.... //let dashes: [CGFloat] = [0.0, itemLength * 2.0] //path.lineCapStyle = CGLineCap.round dotColor.setStroke() path.stroke() } }
我做了垂直,你可以很容易地改变。
只要在场景中放置一个UIView; 使其无论你希望的宽度,这将是虚线的宽度。
只需将该类更改为DottedVertical
,即可完成。 它将在故事板中正确渲染。
请注意,为块的高度(“totalCount”等)给出的示例代码完美地导致块的像素,与创build线的UIView的末端相匹配。
一定要勾选RobMayoff的答案,它给出了点不是块的两个必要的代码行。
将线条帽样式设置为圆形,并将“开”长度设置为零。
Swift游乐场的例子:
import UIKit import XCPlayground let path = UIBezierPath() path.move(to: CGPoint(x:10,y:10)) path.addLine(to: CGPoint(x:290,y:10)) path.lineWidth = 8 let dashes: [CGFloat] = [path.lineWidth * 0, path.lineWidth * 2] path.setLineDash(dashes, count: dashes.count, phase: 0) path.lineCapStyle = CGLineCap.round UIGraphicsBeginImageContextWithOptions(CGSize(width:300, height:20), false, 2) path.stroke() XCPlaygroundPage.currentPage.captureValue(UIGraphicsGetImageFromCurrentImageContext(), withIdentifier: "image") UIGraphicsEndImageContext()
结果:
对于Objective-C,使用与问题中相同的示例类,只需添加
CGContextSetLineCap(cx, kCGLineCapRound);
之前调用CGContextStrokePath
,并更改ra
数组值以匹配我的Swift代码。
上面的Swift示例的Objective-C版本:
UIBezierPath * path = [[UIBezierPath alloc] init]; [path moveToPoint:CGPointMake(10.0, 10.0)]; [path addLineToPoint:CGPointMake(290.0, 10.0)]; [path setLineWidth:8.0]; CGFloat dashes[] = { path.lineWidth, path.lineWidth * 2 }; [path setLineDash:dashes count:2 phase:0]; [path setLineCapStyle:kCGLineCapRound]; UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 20), false, 2); [path stroke]; UIImage * image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
使用一个UIView扩展,与Swift 3.0兼容,以下应该工作:
extension UIView { func addDashedBorder(strokeColor: UIColor, lineWidth: CGFloat) { self.layoutIfNeeded() let strokeColor = strokeColor.cgColor let shapeLayer:CAShapeLayer = CAShapeLayer() let frameSize = self.frame.size let shapeRect = CGRect(x: 0, y: 0, width: frameSize.width, height: frameSize.height) shapeLayer.bounds = shapeRect shapeLayer.position = CGPoint(x: frameSize.width/2, y: frameSize.height/2) shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.strokeColor = strokeColor shapeLayer.lineWidth = lineWidth shapeLayer.lineJoin = kCALineJoinRound shapeLayer.lineDashPattern = [5,5] // adjust to your liking shapeLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: shapeRect.width, height: shapeRect.height), cornerRadius: self.layer.cornerRadius).cgPath self.layer.addSublayer(shapeLayer) } }
然后,在viewDidLoad
之后运行的函数(如viewDidLayoutSubviews
,在相关视图上运行addDashedBorder
函数:
class ViewController: UIViewController { var someView: UIView! override func viewDidLoad() { super.viewDidLoad() someView = UIView() someView.layer.cornerRadius = 5.0 view.addSubview(someView) someView.translatesAutoresizingMaskIntoConstraints = false someView.widthAnchor.constraint(equalToConstant: 200).isActive = true someView.heightAnchor.constraint(equalToConstant: 200).isActive = true someView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true someView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true } override func viewDidLayoutSubviews() { someView.addDashedBorder(strokeColor: UIColor.red, lineWidth: 1.0) } }
我工作了一下rob mayoff接受的解决scheme,轻松定制虚线:
- 改变每个圆的半径。
- 更改2个圆圈之间的空格数目。
- 更改要生成的模式的数量。
该函数返回一个UIImage:
extension UIImage { class func dottedLine(radius radius: CGFloat, space: CGFloat, numberOfPattern: CGFloat) -> UIImage { let path = UIBezierPath() path.moveToPoint(CGPointMake(radius/2, radius/2)) path.addLineToPoint(CGPointMake((numberOfPattern)*(space+1)*radius, radius/2)) path.lineWidth = radius let dashes: [CGFloat] = [path.lineWidth * 0, path.lineWidth * (space+1)] path.setLineDash(dashes, count: dashes.count, phase: 0) path.lineCapStyle = CGLineCap.Round UIGraphicsBeginImageContextWithOptions(CGSizeMake((numberOfPattern)*(space+1)*radius, radius), false, 1) UIColor.whiteColor().setStroke() path.stroke() let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } }
这里是如何获得图像:
UIImage.dottedLine(radius: 100, space: 2, numberOfPattern: 1)
大家好这个解决scheme为我工作得很好。 我find了一些地方,并改变了一点,以防止控制台警告。
extension UIImage { static func drawDottedImage(width: CGFloat, height: CGFloat, color: UIColor) -> UIImage { let path = UIBezierPath() path.move(to: CGPoint(x: 1.0, y: 1.0)) path.addLine(to: CGPoint(x: width, y: 1)) path.lineWidth = 1.5 let dashes: [CGFloat] = [path.lineWidth, path.lineWidth * 5] path.setLineDash(dashes, count: 2, phase: 0) path.lineCapStyle = .butt UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 2) color.setStroke() path.stroke() let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return image } }
这是结果:
在swift 3.1中你可以使用下面的代码:
context.setLineCap(.round)
有三种风格:
/* Line cap styles. */ public enum CGLineCap : Int32 { case butt case round case square }
我已经实现了下面的一段代码,在viewDidAppear
的titleLabel
( UILabel
)的底部添加了带虚线样式的边框:
CAShapeLayer *shapelayer = [CAShapeLayer layer]; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(0.0, titileLabel.frame.size.height-2)]; [path addLineToPoint:CGPointMake(SCREEN_WIDTH, titileLabel.frame.size.height-2)]; UIColor *fill = [UIColor colorWithRed:0.80f green:0.80f blue:0.80f alpha:1.00f]; shapelayer.strokeStart = 0.0; shapelayer.strokeColor = fill.CGColor; shapelayer.lineWidth = 2.0; shapelayer.lineJoin = kCALineJoinRound; shapelayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:2],[NSNumber numberWithInt:3 ], nil]; shapelayer.path = path.CGPath; [titileLabel.layer addSublayer:shapelayer];
参考: https : //gist.github.com/kaiix/4070967
- Xcode只能重构C和Objective-C的代码。 如何重命名在Xcode 6中的Swift类名?
- libsqlite3.dylib和libsqlite3.0.dylib有什么区别?
- iOS应用程序“下一个”键将不会转到下一个文本字段
- 如何在Swift中为UIImageView对象分配一个动作
- 处理iPad迷你屏幕尺寸
- 当iOS 7中显示工作表/提醒时,如何在自定义绘制的控件上将tintColor设置为灰色?
- Xcode 8,iOS 10 – “启动WebFilterlogin进程”
- 如何实现CoreDatalogging的重新sorting?
- 无法使用标识符Cell出队 – 必须为该标识符注册一个nib或一个类,或者在故事板中连接一个原型单元格