UIView 的圆顶角并添加边框
Posted
技术标签:
【中文标题】UIView 的圆顶角并添加边框【英文标题】:Round top corners of a UIView and add border 【发布时间】:2014-03-14 16:08:14 【问题描述】:我在进行圆角处理的类别中有以下代码。我也想画个边框。但边角的圆角部分不显示边框。
这里是代码
- (void) roundTopCorners:(CGFloat) radius
self.layer.masksToBounds = YES;
CGRect bounds = self.bounds;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bounds;
maskLayer.path = maskPath.CGPath;
maskLayer.strokeColor = [UIColor redColor].CGColor;
self.layer.mask = maskLayer;
【问题讨论】:
"请注意,如果您尝试在动态调整大小的视图(例如响应自动旋转)上使用这种框架样式,则必须更加小心,因为图层可以'不要利用自动布局。在这种情况下,您最好的解决方案可能是创建一个自定义 UITextField 并实现 layerClass 以返回一个自定义图层类,该类可以动态调整类似于上面创建的图层的大小。@David Berry“实际上并不那么棘手,如果你想调整所有这些层的大小,只需将所有代码放在 viewDidAppear 中,它就可以工作! 【参考方案1】:不绘制遮罩层,仅用于计算遮罩。试试:
-(void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius
CGRect bounds = self.bounds;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds
byRoundingCorners:corners
cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bounds;
maskLayer.path = maskPath.CGPath;
self.layer.mask = maskLayer;
CAShapeLayer* frameLayer = [CAShapeLayer layer];
frameLayer.frame = bounds;
frameLayer.path = maskPath.CGPath;
frameLayer.strokeColor = [UIColor redColor].CGColor;
frameLayer.fillColor = nil;
[self.layer addSublayer:frameLayer];
-(void)roundTopCornersRadius:(CGFloat)radius
[self roundCorners:(UIRectCornerTopLeft|UIRectCornerTopRight) radius:radius];
-(void)roundBottomCornersRadius:(CGFloat)radius
[self roundCorners:(UIRectCornerBottomLeft|UIRectCornerBottomRight) radius:radius];
您当前看到的框架是 UITextField 的正常框架,因此请将框架样式设置为无。您还必须调整插图以弥补框架样式设置为 none 时通常没有插图这一事实。
【讨论】:
请注意,如果您尝试在动态调整大小(例如响应自动旋转)的视图上使用这种框架样式,则必须更加小心,因为图层可以' t 利用自动布局。在这种情况下,您最好的解决方案可能是创建一个自定义 UITextField 并实现 layerClass 以返回一个自定义图层类,该类可以动态调整图层的大小,类似于上面创建的图层。 这是一个好方法。但是,边框不会是正确的厚度。这是因为边框的描边一半在蒙版之内,一半在蒙版之外。很容易修复 - 只需添加以下内容:frameLayer.lineWidth = borderWidth*2;
其中borderWidth 是您想要的边框宽度。
@BooTooMany 在某些时候有类似的东西来解释线宽。我想我实际上是在适当的量内插入路径,但是将厚度加倍的效果大致相同并且更简单。
如何在uitableviewcell中调用这些方法【参考方案2】:
David Berry 回答的 Swift 版本:
func roundCorners(corners:UIRectCorner, radius:CGFloat)
let bounds = self.bounds
let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSizeMake(radius, radius))
let maskLayer = CAShapeLayer()
maskLayer.frame = bounds
maskLayer.path = maskPath.CGPath
self.layer.mask = maskLayer
let frameLayer = CAShapeLayer()
frameLayer.frame = bounds
frameLayer.path = maskPath.CGPath
frameLayer.strokeColor = UIColor.redColor().CGColor
frameLayer.fillColor = nil
self.layer.addSublayer(frameLayer)
func roundTopCornersRadius(radius:CGFloat)
self.roundCorners([UIRectCorner.TopLeft, UIRectCorner.TopRight], radius:radius)
func roundBottomCornersRadius(radius:CGFloat)
self.roundCorners([UIRectCorner.BottomLeft, UIRectCorner.BottomRight], radius:radius)
【讨论】:
很棒的东西。干杯。【参考方案3】:这可能是一个很晚的答案,但我只想分享我根据不同人对不同类似问题的答案提出的解决方案。我从上面 Vojtech 的回答中得到了很大的帮助。
extension UIView
func EZRoundCorners(corners:UIRectCorner, radius: CGFloat) -> CAShapeLayer
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.CGPath
self.layer.mask = mask
return mask
func EZRoundCornersWithBorder(corners:UIRectCorner, radius:CGFloat, color:UIColor, width:CGFloat) -> CAShapeLayer
let mask = self.EZRoundCorners(corners, radius: radius)
// Add border
let borderLayer = EZCALayer()
borderLayer.path = mask.path // Reuse the Bezier path
borderLayer.fillColor = UIColor.clearColor().CGColor
borderLayer.strokeColor = color.CGColor
borderLayer.lineWidth = width
borderLayer.frame = self.bounds
self.layer.addSublayer(borderLayer)
return borderLayer
func removeEZLayers ()
for layer in self.layer.sublayers!
if layer is EZCALayer
layer.removeFromSuperlayer()
class EZCALayer : CAShapeLayer
我从 CAShapeLayer 继承,所以如果我不想再使用它们,我可以删除边框子层。
【讨论】:
【参考方案4】: label.layer.cornerRadius = 3.0
label.layer.maskedCorners = [.layerMinXMinYCorner,.layerMinXMaxYCorner]//round top left and bottom left corners
来源:https://www.hackingwithswift.com/example-code/calayer/how-to-round-only-specific-corners-using-maskedcorners
Image of working solution
【讨论】:
以上是关于UIView 的圆顶角并添加边框的主要内容,如果未能解决你的问题,请参考以下文章