圆化 UIView 的一些角并圆化视图层的边框

Posted

技术标签:

【中文标题】圆化 UIView 的一些角并圆化视图层的边框【英文标题】:Round some corners of UIView and round the view’s layer’s border too 【发布时间】:2013-02-14 01:38:38 【问题描述】:

我正在尝试将 UIView 的底部两个角变圆,并使图层的边框也变圆。我目前正在做:

UIRectCorners corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
CGSize radii = CGSizeMake(kThisViewCornerRadius, kThisViewCornerRadius);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:myView.bounds
                                           byRoundingCorners:corners
                                                 cornerRadii:radii];

CAShapeLayer *maskLayer = [CAShapeLayer layer];
[maskLayer setPath:path.CGPath];
myView.layer.mask = maskLayer;

这适用于普通视图。但是,myView 的图层有其borderColorborderWidth 设置,从截图中可以看出,图层的边框没有变圆:

我还尝试子类化 UIView 并从 +[Class layerClass] 返回 [CAShapeLayer layer],并将视图的图层设置为一个形状图层,但边框最终位于视图的子视图下方。

是否可以圆化视图的某些角,圆化视图层的边框,并将子视图裁剪到层的边框下方?

请注意,这不是关于如何圆角而不是其他角,而是关于如何使笔划正确运行。

【问题讨论】:

添加一个被描边到图层层次结构中的形状图层? 好建议,但我测试了它,形状图层的笔触仍然显示在视图的子视图后面。 实际上,您的评论让我想到了正确的方向,最终我明白了。我会发布它作为答案。谢谢! Rounded UIView using CALayers - only some corners - How?的可能重复 【参考方案1】:

感谢David Rönnqvist 的评论,我找到了一种新的思考方式。

我试图在一层中进行圆角和笔触。相反,我将其分为两层:一层用于遮罩视图层以圆角,另一层在视图中添加笔触。

UIView *containerView = [[UIView alloc] initWithFrame:someFrame];

UIRectCorners corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
CGSize radii = CGSizeMake(kThisViewCornerRadius, kThisViewCornerRadius);

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:myView.bounds
                                           byRoundingCorners:corners
                                                 cornerRadii:radii];

// Mask the container view’s layer to round the corners.
CAShapeLayer *cornerMaskLayer = [CAShapeLayer layer];
[cornerMaskLayer setPath:path.CGPath];
containerView.layer.mask = cornerMaskLayer;

// Make a transparent, stroked layer which will dispay the stroke.
CAShapeLayer *strokeLayer = [CAShapeLayer layer];
strokeLayer.path = path.CGPath;
strokeLayer.fillColor = [UIColor clearColor].CGColor;
strokeLayer.strokeColor = [UIColor redColor].CGColor;
strokeLayer.lineWidth = 2; // the stroke splits the width evenly inside and outside,
                           // but the outside part will be clipped by the containerView’s mask.

// Transparent view that will contain the stroke layer
UIView *strokeView = [[UIView alloc] initWithFrame:containerView.bounds];
strokeView.userInteractionEnabled = NO; // in case your container view contains controls
[strokeView.layer addSublayer:strokeLayer];

// configure and add any subviews to the container view

// stroke view goes in last, above all the subviews
[containerView addSubview:strokeView];

【讨论】:

非常好!但是我可以用这个设置可选的边框吗? 可选边框是什么意思?【参考方案2】:

Zev Eisenberg 的答案是正确的。

虽然我更喜欢:

[self.layer addSublayer:strokeLayer];

而不是创建和添加子视图:

CGSize radii = CGSizeMake(radius, radius);

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds
                                           byRoundingCorners:corners
                                                 cornerRadii:radii];

// Mask the container view’s layer to round the corners.
CAShapeLayer *cornerMaskLayer = [CAShapeLayer layer];
[cornerMaskLayer setPath:path.CGPath];
self.layer.mask = cornerMaskLayer;

// Make a transparent, stroked layer which will dispay the stroke.
CAShapeLayer *strokeLayer = [CAShapeLayer layer];
strokeLayer.path = path.CGPath;
strokeLayer.fillColor = [UIColor clearColor].CGColor;
strokeLayer.strokeColor = color.CGColor;
strokeLayer.lineWidth = 2; // the stroke splits the width evenly inside and outside,
// but the outside part will be clipped by the containerView’s mask.

[self.layer addSublayer:strokeLayer];

【讨论】:

【参考方案3】:

这是小代码。 Alloc 初始化一个视图并发送到此方法以获取圆角。您可以选择绕过您想要的任何角落。还要给阴影描边颜色。

 -(void) setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners withColor:  (UIColor*) color

 UIBezierPath* rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds  byRoundingCorners:corners cornerRadii:CGSizeMake(9.0, 9.0)];

CAShapeLayer* shape = [[[CAShapeLayer alloc] init] autorelease];
[shape setPath:rounded.CGPath];
shape.strokeColor = [[UIColor grayColor] CGColor];

view.backgroundColor=color;
view.layer.mask = shape;

像这样调用方法。

[self setMaskTo:ABCView byRoundingCorners:UIRectCornerAllCorners withColor:[UIColor greenColor]];

【讨论】:

以上是关于圆化 UIView 的一些角并圆化视图层的边框的主要内容,如果未能解决你的问题,请参考以下文章

UIView 的圆顶角并添加边框

如何仅舍入 UILabel 的前两个角?

IOS / Objective-C:矩形的圆顶角不擦除边框

如何用 Swift 圆化 UILabel 的边缘

与其他 UIView 边框线重叠时的 UIView 边框线粗细

如何在 tableView 单元格中圆化 UIImageView 的角