带边框的cornerRadius:边界周围有毛刺

我的申请大多是圆形和边界的。

我使用UIView的图层属性来给出角半径和边框。

但我面临的问题是角落不清楚。

我得到以下结果:

的UIButton

带圆角和边框的按钮的屏幕截图

的UIImageView

带圆角和边框的图像视图的屏幕截图

您可以观察到白色或灰色边框周围的细边框线。

这是我的代码:

 button.layer.borderWidth = 2.0; button.layer.borderColor = [[UIColor whiteColor] CGColor]; button.layer.cornerRadius = 4; button.clipsToBounds = YES; 

我已经寻求解决这个问题,但我没有成功。

我尝试过button.layer.masksToBounds = YES ,但没有效果。

我错过了什么吗? 还是有其他方法可以比CALayer更好的结果?

我尝试了很多解决方案并使用UIBezierPath结束。

我创建UIView类别并添加方法来制作圆形矩形和边框。

这是该类别的方法:

 - (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]; } 

我从这篇惊人的文章中得到了使用UIBezierPath想法: 像Bézier路径一样思考

我从这两个链接获得了大部分代码:

  • UIView类别用于舍入您想要的角落,而不是像CALayer cornerRadius一样。
  • 如何在UIBezierPath上获取边框

注意:这是类别方法,因此自我表示调用此方法的视图。 像UIButton,UIImageView等。

这是我的Swift版本的@ CRDave的答案作为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.clearColor().CGColor borderLayer.lineWidth = borderWidth * UIScreen.mainScreen().scale //Add this layer to give border. self.layer.addSublayer(borderLayer) } } 

这是Kamil Nomtek.com的答案更新为Swift 3/4并进行了一些改进(主要是语义/命名和使用类协议)。

 protocol RoundedBorderProtocol: class { func makeBorder(with radius: CGFloat, borderWidth: CGFloat, borderColor: UIColor) } extension UIView: RoundedBorderProtocol { func makeBorder(with radius: CGFloat, borderWidth: CGFloat, borderColor: UIColor) { let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: radius, height: radius)) // Create the shape layer and set its path let maskLayer = CAShapeLayer() maskLayer.frame = bounds maskLayer.path = maskPath.cgPath // Set the newly created shape layer as the mask for the view's layer layer.mask = maskLayer //Create path for border let borderPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: radius, height: radius)) // Create the shape layer and set its path let borderLayer = CAShapeLayer() borderLayer.frame = bounds borderLayer.path = borderPath.cgPath borderLayer.strokeColor = borderColor.cgColor borderLayer.fillColor = UIColor.clear.cgColor //The border is in the center of the path, so only the inside is visible. //Since only half of the line is visible, we need to multiply our width by 2. borderLayer.lineWidth = borderWidth * 2 //Add this layer to display the border layer.addSublayer(borderLayer) } } 

CRDave的答案效果很好但有一个缺陷:当多次调用大小变化时,它会不断添加图层。 而是应该更新以前的图层。
请参阅下面的更新ObjC版本。 对于swift,请相应调整。

 // UIView+Border.h #import  @interface UIView (Border) - (void)setBorderWithCornerRadius:(CGFloat)radius color:(UIColor *)borderColor width:(CGFloat)borderWidth; @end // UIView+Border.m #import "UIView+Border.h" @implementation UIView (Border) - (void)setBorderWithCornerRadius:(CGFloat)radius color:(UIColor *)borderColor width:(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 NSString *layerName = @"ig_border_layer"; CAShapeLayer *borderLayer = (CAShapeLayer *)[[[self.layer sublayers] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name == %@", layerName]] firstObject]; if (!borderLayer) { borderLayer = [CAShapeLayer layer]; [borderLayer setName:layerName]; //Add this layer to give border. [[self layer] addSublayer:borderLayer]; } borderLayer.frame = rect; borderLayer.path = borderPath.CGPath; borderLayer.strokeColor = [UIColor whiteColor].CGColor; borderLayer.fillColor = [UIColor clearColor].CGColor; borderLayer.lineWidth = borderWidth; } @end 

删除

 button.layer.borderWidth = 0.3; button.layer.borderColor = [[UIColor blueMain] CGColor];