What I have:
To create this line, I basically have a
Dash Line in Swift4 • Xcode 9
Crate a CAShapeLayer & use lineDashPattern
extension UIView {
func addDashedBorder() {
//Create a CAShapeLayer
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 2
// passing an array with the values [2,3] sets a dash pattern that alternates between a 2-user-space-unit-long painted segment and a 3-user-space-unit-long unpainted segment
shapeLayer.lineDashPattern = [2,3]
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: 0, y: 0),
CGPoint(x: self.frame.width, y: 0)])
shapeLayer.path = path
layer.addSublayer(shapeLayer)
}
}
Usage:
dashView.addDashedBorder()
Output:
The accepted answer has a coordinate problem. The line will be drawn some distance below. And I cannot figure out why and how much distance it increases on Y coordinate.
There's a way to draw a dashed line with correct coordinate:
-(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);
}
This answer is from Draw dotted (not dashed!) line, with IBDesignable in 2017. DON'T DON'T DON'T forget to set the background color as white when you want a black dashed line!! By default the view has a black background color, and the line color is also black, so I thought it was a solid line. It cost me half a day to find out. T_T
Swift 2.2
dropping this in here to save others time..
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)
}
}
First all the credit goes to RuiAAPeres and Prince, I'm just encapsulating their answers into a UIView object that others can drop into their projects and use
#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
Check UIBezierPath setLineDash:count:phase:
method:
- (void)setLineDash:(const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase` method.
This allows you to draw dashed lines.
CAShapeLayer
. Add it as sublayer to your UIView
. It has a path
property. UIBezierPath
. Draw the line using setLineDash
.For example:
UIBezierPath *path = [UIBezierPath bezierPath];
//draw a line
[path moveToPoint:yourStartPoint]; //add yourStartPoint here
[path addLineToPoint:yourEndPoint];// add yourEndPoint here
[path stroke];
CGFloat dashPattern[] = {2.0f,6.0f,4.0f,2.0f}; //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;
Note: This answer provides a hint so you can improvise accordingly to your requirement(s).
Here is Swift 3 version of Alexandre G's answer 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)
}
}