UIView用虚线

我拥有的:

在这里输入图像说明

要创build这一行,我基本上有一个UIView ,我做了以下几点:

 void setLayerToLineFromAToB(CALayer *layer, CGPoint a, CGPoint b, CGFloat lineWidth) { CGPoint center = { 0.5 * (ax + bx), 0.5 * (ay + by) }; CGFloat length = sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by)); CGFloat angle = atan2(ay - by, ax - bx); layer.position = center; layer.bounds = (CGRect) { {0, 0}, { length + lineWidth, lineWidth } }; layer.transform = CATransform3DMakeRotation(angle, 0, 0, 1); } 

注意:这个代码在这里find了stackoverflow,所以如果有人可以给我的参考,我将不胜感激。

我想要的是:

在这里输入图像说明

好,所以“唯一”我需要的是在UIView上创build这个模式。 我知道我能够使用Quartz2D来做到这一点(一个简单的方法可以在这里find)。 但我想通过操作CALayer而不是去绘制方法。 为什么? 由于我正在对UIView进行的转换,我无法使用draw方法正确draw

编辑1:

只是为了说明我的问题:

在这里输入图像说明

通常你所拥有的是UIView ,然后你基本上只是画一些东西(在这种情况下是一个简单的线)。 我发现摆脱“灰色”区域的解决scheme,而不是绘制的东西,只是转换UIView本身。 它工作的很好,如果你想要一个完整的线,当你想要一个虚线的问题。

检查UIBezierPath's方法:

 - (void)setLineDash:(const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase` method. 

这使您可以draw dashed

1)首先添加CAShapeLayer 。 将它作为sublayer添加到您的UIView layerCAShapeLayer有一个path property

2)现在创build一个UIBezierPath的对象。 使用setLineDash Draw线条。

例如

  UIBezierPath *path = [UIBezierPath bezierPath]; //draw a line [path moveToPoint:yourStartPoint]; //add yourStartPoint here [path addLineToPoint:yourEndPoint];// add yourEndPoint here [path stroke]; float dashPattern[] = {2,6,4,2}; //make your pattern here [path setLineDash:dashPattern count:4 phase:3]; UIColor *fill = [UIColor blueColor]; shapelayer.strokeStart = 0.0; shapelayer.strokeColor = fill.CGColor; shapelayer.lineWidth = 5.0; shapelayer.lineJoin = kCALineJoinMiter; shapelayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:10],[NSNumber numberWithInt:7], nil]; shapelayer.lineDashPhase = 3.0f; shapelayer.path = path.CGPath; 

注:这个答案提供了一个提示,所以你可以根据你的要求凑合。

注意 :王子的代码确实帮了我,所以我会给他+10的提示。 但是最后,我添加了自己的代码。 我也会添加一些上下文,所以对未来的读者可能有用


最终的代码是这样的:

 -(void)updateLine{ // Important, otherwise we will be adding multiple sub layers if ([[[self layer] sublayers] objectAtIndex:0]) { self.layer.sublayers = nil; } CAShapeLayer *shapeLayer = [CAShapeLayer layer]; [shapeLayer setBounds:self.bounds]; [shapeLayer setPosition:self.center]; [shapeLayer setFillColor:[[UIColor clearColor] CGColor]]; [shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]]; [shapeLayer setLineWidth:3.0f]; [shapeLayer setLineJoin:kCALineJoinRound]; [shapeLayer setLineDashPattern: [NSArray arrayWithObjects:[NSNumber numberWithInt:10], [NSNumber numberWithInt:5],nil]]; // Setup the path CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, beginPoint.center.x, beginPoint.center.y); CGPathAddLineToPoint(path, NULL, endPoint.center.x, endPoint.center.y); [shapeLayer setPath:path]; CGPathRelease(path); [[self layer] addSublayer:shapeLayer]; } 

在我的情况下,beginPoint和endPoint可以由用户通过使用KVO来移动。 所以当他们中的一个动作时:

 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqual:@"position"]) { [self updateLine]; } } 

我用王子的密码玩了很多。 我尝试了draw:方法,它在虚线之间添加了一条细线(有点奇怪…),我也尝试了initWithFrame: 就其本身而言,他的代码没有任何修改就会在控制台上给我这种错误:

 <Error>: CGContextSaveGState: invalid context 0x0 <Error>: CGContextSetLineWidth: invalid context 0x0 <Error>: CGContextSetLineJoin: invalid context 0x0 <Error>: CGContextSetLineCap: invalid context 0x0 <Error>: CGContextSetMiterLimit: invalid context 0x0 <Error>: CGContextSetFlatness: invalid context 0x0 <Error>: CGContextAddPath: invalid context 0x0 <Error>: CGContextDrawPath: invalid context 0x0 <Error>: CGContextRestoreGState: invalid context 0x0 

Swift 2.2

在这里放下这个节省时间..

 extension UIView { func addDashedLine(color: UIColor = UIColor.lightGrayColor()) { layer.sublayers?.filter({ $0.name == "DashedTopLine" }).map({ $0.removeFromSuperlayer() }) self.backgroundColor = UIColor.clearColor() let cgColor = color.CGColor let shapeLayer: CAShapeLayer = CAShapeLayer() let frameSize = self.frame.size let shapeRect = CGRect(x: 0, y: 0, width: frameSize.width, height: frameSize.height) shapeLayer.name = "DashedTopLine" shapeLayer.bounds = shapeRect shapeLayer.position = CGPoint(x: frameSize.width / 2, y: frameSize.height / 2) shapeLayer.fillColor = UIColor.clearColor().CGColor shapeLayer.strokeColor = cgColor shapeLayer.lineWidth = 1 shapeLayer.lineJoin = kCALineJoinRound shapeLayer.lineDashPattern = [4, 4] let path: CGMutablePathRef = CGPathCreateMutable() CGPathMoveToPoint(path, nil, 0, 0) CGPathAddLineToPoint(path, nil, self.frame.width, 0) shapeLayer.path = path self.layer.addSublayer(shapeLayer) } } 

这里是亚历山大G的Swift 3版的回答https://stackoverflow.com/a/38194152/1800489

 extension UIView { func addDashedLine(color: UIColor = .lightGray) { layer.sublayers?.filter({ $0.name == "DashedTopLine" }).map({ $0.removeFromSuperlayer() }) backgroundColor = .clear let shapeLayer = CAShapeLayer() shapeLayer.name = "DashedTopLine" shapeLayer.bounds = bounds shapeLayer.position = CGPoint(x: frame.width / 2, y: frame.height / 2) shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.strokeColor = color.cgColor shapeLayer.lineWidth = 1 shapeLayer.lineJoin = kCALineJoinRound shapeLayer.lineDashPattern = [4, 4] let path = CGMutablePath() path.move(to: CGPoint.zero) path.addLine(to: CGPoint(x: frame.width, y: 0)) shapeLayer.path = path layer.addSublayer(shapeLayer) } } 

首先所有的功劳都归功于RuiAAPeres和Prince,我只是把他们的答案封装到一个UIView对象中,其他人可以放入他们的项目并使用

 #import <UIKit/UIKit.h> /** * Simple UIView for a dotted line */ @interface H3DottedLine : UIView /** * Set the line's thickness */ @property (nonatomic, assign) CGFloat thickness; /** * Set the line's color */ @property (nonatomic, copy) UIColor *color; /** * Set the length of the dash */ @property (nonatomic, assign) CGFloat dashedLength; /** * Set the gap between dashes */ @property (nonatomic, assign) CGFloat dashedGap; @end @implementation H3DottedLine #pragma mark - Object Lifecycle - (instancetype)init { self = [super init]; if (self) { // Set Default Values _thickness = 1.0f; _color = [UIColor whiteColor]; _dashedGap = 1.0f; _dashedLength = 5.0f; } return self; } #pragma mark - View Lifecycle - (void)layoutSubviews { // Note, this object draws a straight line. If you wanted the line at an angle you simply need to adjust the start and/or end point here. [self updateLineStartingAt:self.frame.origin andEndPoint:CGPointMake(self.frame.origin.x+self.frame.size.width, self.frame.origin.y)]; } #pragma mark - Setters - (void)setThickness:(CGFloat)thickness { _thickness = thickness; [self setNeedsLayout]; } - (void)setColor:(UIColor *)color { _color = [color copy]; [self setNeedsLayout]; } - (void)setDashedGap:(CGFloat)dashedGap { _dashedGap = dashedGap; [self setNeedsLayout]; } - (void)setDashedLength:(CGFloat)dashedLength { _dashedLength = dashedLength; [self setNeedsLayout]; } #pragma mark - Draw Methods -(void)updateLineStartingAt:(CGPoint)beginPoint andEndPoint:(CGPoint)endPoint { // Important, otherwise we will be adding multiple sub layers if ([[[self layer] sublayers] objectAtIndex:0]) { self.layer.sublayers = nil; } CAShapeLayer *shapeLayer = [CAShapeLayer layer]; [shapeLayer setBounds:self.bounds]; [shapeLayer setPosition:self.center]; [shapeLayer setFillColor:[UIColor clearColor].CGColor]; [shapeLayer setStrokeColor:self.color.CGColor]; [shapeLayer setLineWidth:self.thickness]; [shapeLayer setLineJoin:kCALineJoinRound]; [shapeLayer setLineDashPattern:@[@(self.dashedLength), @(self.dashedGap)]]; // Setup the path CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, beginPoint.x, beginPoint.y); CGPathAddLineToPoint(path, NULL, endPoint.x, endPoint.y); [shapeLayer setPath:path]; CGPathRelease(path); [[self layer] addSublayer:shapeLayer]; } @end 

接受的答案有一个协调问题。 该线将被绘制在一定的距离以下。 而我不知道为什么和Y坐标增加了多less距离。

有一种方法可以用正确的坐标绘制虚线:

 -(void)drawRect:(CGRect)rect { CGContextBeginPath(cx); CGContextRef cx = UIGraphicsGetCurrentContext(); CGContextSetLineWidth(cx, _thickness); CGContextSetStrokeColorWithColor(cx, _color.CGColor); CGFloat dash[] = {_dashedLength,_dashedGap}; CGContextSetLineDash(cx, 0, dash, 2); // nb "2" == ra count // CGContextSetLineCap(cx, kCGLineCapRound); CGContextMoveToPoint(cx, 0, _thickness); CGContextAddLineToPoint(cx, self.bounds.size.width, _thickness); CGContextStrokePath(cx); CGContextClosePath(cx); } 

这个答案来自Draw dotted(不是虚线),在2017年有了IBDesignable 。 当你想要一个黑色的虚线时,不要忘了设置背景颜色为白色! 默认情况下,视图有黑色的背景颜色,线条颜色也是黑色的,所以我认为这是一条实线。 花费我半天的时间才能知道。 T_T