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 layer
。 CAShapeLayer
有一个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