How do I add dashed line border around UIView
.
Something Like this
Swift solution with custom class worked with autolayout
customized from @Iain Smith
class DashedBorderView: UIView {
@IBInspectable var cornerRadius: CGFloat = 4
@IBInspectable var borderColor: UIColor = UIColor.black
@IBInspectable var dashPaintedSize: Int = 2
@IBInspectable var dashUnpaintedSize: Int = 2
let dashedBorder = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
//custom initialization
self.layer.addSublayer(dashedBorder)
applyDashBorder()
}
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
applyDashBorder()
}
func applyDashBorder() {
dashedBorder.strokeColor = borderColor.cgColor
dashedBorder.lineDashPattern = [NSNumber(value: dashPaintedSize), NSNumber(value: dashUnpaintedSize)]
dashedBorder.fillColor = nil
dashedBorder.cornerRadius = cornerRadius
dashedBorder.path = UIBezierPath(rect: self.bounds).cgPath
dashedBorder.frame = self.bounds
}
}
If you want this to work with cornerRadius then try this
tagView.clipsToBounds = YES;
tagView.layer.cornerRadius = 20.0f;
tagView.backgroundColor = [UIColor groupTableViewBackgroundColor];
CAShapeLayer *yourViewBorder = [CAShapeLayer layer];
yourViewBorder.strokeColor = [UIColor blackColor].CGColor;
yourViewBorder.fillColor = nil;
yourViewBorder.lineDashPattern = @[@2, @2];
yourViewBorder.frame = tagView.bounds;
// Create the path for to make circle
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:tagView.bounds
byRoundingCorners:UIRectCornerAllCorners
cornerRadii:CGSizeMake(20, 20)];
yourViewBorder.path = maskPath.CGPath;
[tagView.layer addSublayer:yourViewBorder];
Here is a UIView subclass that can work for any project, it also works for round views:
import UIKit
class CustomDashedView: UIView {
@IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
@IBInspectable var dashWidth: CGFloat = 0
@IBInspectable var dashColor: UIColor = .clear
@IBInspectable var dashLength: CGFloat = 0
@IBInspectable var betweenDashesSpace: CGFloat = 0
var dashBorder: CAShapeLayer?
override func layoutSubviews() {
super.layoutSubviews()
dashBorder?.removeFromSuperlayer()
let dashBorder = CAShapeLayer()
dashBorder.lineWidth = dashWidth
dashBorder.strokeColor = dashColor.cgColor
dashBorder.lineDashPattern = [dashLength, betweenDashesSpace] as [NSNumber]
dashBorder.frame = bounds
dashBorder.fillColor = nil
if cornerRadius > 0 {
dashBorder.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
} else {
dashBorder.path = UIBezierPath(rect: bounds).cgPath
}
layer.addSublayer(dashBorder)
self.dashBorder = dashBorder
}
}
This way you can edit from the Storyboard like this:
A pair of results:
You can set the border with this pattern using Layer and Bezier path like below examples.
Objective-C
CAShapeLayer *yourViewBorder = [CAShapeLayer layer];
yourViewBorder.strokeColor = [UIColor blackColor].CGColor;
yourViewBorder.fillColor = nil;
yourViewBorder.lineDashPattern = @[@2, @2];
yourViewBorder.frame = yourView.bounds;
yourViewBorder.path = [UIBezierPath bezierPathWithRect:yourView.bounds].CGPath;
[yourView.layer addSublayer:yourViewBorder];
Swift 3.1
var yourViewBorder = CAShapeLayer()
yourViewBorder.strokeColor = UIColor.black.cgColor
yourViewBorder.lineDashPattern = [2, 2]
yourViewBorder.frame = yourView.bounds
yourViewBorder.fillColor = nil
yourViewBorder.path = UIBezierPath(rect: yourView.bounds).cgPath
yourView.layer.addSublayer(yourViewBorder)
You can also set different types of design using pattern image like below example.
[yourView.layer setBorderWidth:5.0];
[yourView.layer setBorderColor:[[UIColor colorWithPatternImage:[UIImage imageNamed:@"DotedImage.png"]] CGColor]];///just add image name and create image with dashed or doted drawing and add here
Here you've to add <QuartzCore/QuartzCore>
framework in the project and import it with below line in YourViewController.m
file.
#import <QuartzCore/QuartzCore.h>
Use CGContextSetLineDash() method.
CGFloat dashPattern[]= {3.0, 2};
context =UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
// And draw with a blue fill color
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
// Draw them with a 2.0 stroke width so they are a bit more visible.
CGContextSetLineWidth(context, 4.0);
CGContextSetLineDash(context, 0.0, dashPattern, 2);
CGContextAddRect(context, self.bounds);
// Close the path
CGContextClosePath(context);
CGContextStrokePath(context);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
I think it will be helpful to you.
Building upon what Prasad G has suggested I created a method inside a UIImage Extras class with the following:
- (CAShapeLayer *) addDashedBorderWithColor: (CGColorRef) color {
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
CGSize frameSize = self.size;
CGRect shapeRect = CGRectMake(0.0f, 0.0f, frameSize.width, frameSize.height);
[shapeLayer setBounds:shapeRect];
[shapeLayer setPosition:CGPointMake( frameSize.width/2,frameSize.height/2)];
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]];
[shapeLayer setStrokeColor:color];
[shapeLayer setLineWidth:5.0f];
[shapeLayer setLineJoin:kCALineJoinRound];
[shapeLayer setLineDashPattern:
[NSArray arrayWithObjects:[NSNumber numberWithInt:10],
[NSNumber numberWithInt:5],
nil]];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0];
[shapeLayer setPath:path.CGPath];
return shapeLayer;
}
It's important to point out that if you define your shape's position as (0,0), the bottom corner of the border will be placed in the center of the image, that's why I set it to: (frameSize.width/2,frameSize.height/2)
I then use my method to get the dashed border using the UIImage of my UIImageView and add the CAShapeLayer as a sublayer of the UIImageView layer:
[myImageView.layer addSublayer:[myImageView.image addDashedBorderWithColor:[[UIColor whiteColor] CGColor]]];