cornerRadius with border: Glitch around border
Here is a Swift 5 version of @CRDave's answer as an extension of UIView:
protocol CornerRadius {
func makeBorderWithCornerRadius(radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat)
}
extension UIView: CornerRadius {
func makeBorderWithCornerRadius(radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
let rect = self.bounds
let maskPath = UIBezierPath(roundedRect: rect,
byRoundingCorners: .allCorners,
cornerRadii: CGSize(width: radius, height: radius))
// Create the shape layer and set its path
let maskLayer = CAShapeLayer()
maskLayer.frame = rect
maskLayer.path = maskPath.cgPath
// Set the newly created shape layer as the mask for the view's layer
self.layer.mask = maskLayer
// Create path for border
let borderPath = UIBezierPath(roundedRect: rect,
byRoundingCorners: .allCorners,
cornerRadii: CGSize(width: radius, height: radius))
// Create the shape layer and set its path
let borderLayer = CAShapeLayer()
borderLayer.frame = rect
borderLayer.path = borderPath.cgPath
borderLayer.strokeColor = borderColor.cgColor
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.lineWidth = borderWidth * UIScreen.main.scale
//Add this layer to give border.
self.layer.addSublayer(borderLayer)
}
}
I tried many solution and end by using UIBezierPath
.
I create category of UIView
and add method to make round rect and border.
This is method of that category:
- (void)giveBorderWithCornerRadious:(CGFloat)radius borderColor:(UIColor *)borderColor andBorderWidth:(CGFloat)borderWidth
{
CGRect rect = self.bounds;
//Make round
// Create the path for to make circle
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect
byRoundingCorners:UIRectCornerAllCorners
cornerRadii:CGSizeMake(radius, radius)];
// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = rect;
maskLayer.path = maskPath.CGPath;
// Set the newly created shape layer as the mask for the view's layer
self.layer.mask = maskLayer;
//Give Border
//Create path for border
UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:rect
byRoundingCorners:UIRectCornerAllCorners
cornerRadii:CGSizeMake(radius, radius)];
// Create the shape layer and set its path
CAShapeLayer *borderLayer = [CAShapeLayer layer];
borderLayer.frame = rect;
borderLayer.path = borderPath.CGPath;
borderLayer.strokeColor = [UIColor whiteColor].CGColor;
borderLayer.fillColor = [UIColor clearColor].CGColor;
borderLayer.lineWidth = borderWidth;
//Add this layer to give border.
[[self layer] addSublayer:borderLayer];
}
I get idea of using UIBezierPath
from this amazing article: Thinking like a Bézier path
I get most of code from this two link:
- UIView category for rounding just the corners which you want, not all like CALayer cornerRadius.
- How to get a border on UIBezierPath
Note: This is category method so self represent view on which this method is called. Like UIButton, UIImageView etc.