Ios 带边框的拐角半径:边框周围出现故障
我的应用程序大多是基于圆形和边界的 我使用Ios 带边框的拐角半径:边框周围出现故障,ios,objective-c,calayer,Ios,Objective C,Calayer,我的应用程序大多是基于圆形和边界的 我使用UIView的layer属性来指定角半径和边界 但我面临一个问题,即角落不清晰 我得到以下结果: ui按钮 UIImageView 您可以观察白色或灰色边框周围的细边框线 这是我的代码: button.layer.borderWidth = 2.0; button.layer.borderColor = [[UIColor whiteColor] CGColor]; button.layer.cornerRadius = 4; button.cli
UIView
的layer属性来指定角半径和边界
但我面临一个问题,即角落不清晰
我得到以下结果:
ui按钮
UIImageView
您可以观察白色或灰色边框周围的细边框线
这是我的代码:
button.layer.borderWidth = 2.0;
button.layer.borderColor = [[UIColor whiteColor] CGColor];
button.layer.cornerRadius = 4;
button.clipsToBounds = YES;
我试图解决这个问题,但没有成功
我尝试了button.layer.masksToBounds=YES
,但没有效果
我遗漏了什么吗?或者与CALayer相比,有没有其他方法可以给我更好的结果?删除
button.layer.borderWidth = 0.3;
button.layer.borderColor = [[UIColor blueMain] CGColor];
我尝试了许多解决方案,最后使用了
UIBezierPath
我创建了UIView
的类别,并添加了方法来生成圆形rect和border
这是该类别的方法:
- (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
:
我从这两个链接获得了大部分代码:
注意:这是category方法,因此调用此方法的视图是自表示的。与UIButton、UIImageView等类似。以下是@CRDave的Swift 5版本,作为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)
}
}
这已更新为Swift 3+,并进行了一些改进(主要是语义/命名和使用类协议)
CRDave的答案很好,但有一个缺陷:当多次调用时,比如大小更改,它会不断添加层。相反,应更新以前的图层。
有关更新的ObjC版本,请参见下文。对于swift,请进行相应调整
// UIView+Border.h
#import <UIKit/UIKit.h>
@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
//UIView+Border.h
#进口
@界面视图(边框)
-(无效)带拐角半径的立根顺序:(CGFloat)半径
颜色:(UIColor*)边框颜色
宽度:(CGFloat)边框宽度;
@结束
//UIView+Border.m
#导入“UIView+Border.h”
@实现视图(边框)
-(无效)带拐角半径的立根顺序:(CGFloat)半径
颜色:(UIColor*)边框颜色
宽度:(CGFloat)边框宽度{
CGRect rect=自边界;
//兜圈子
//创建用于创建圆的路径
UIBezierPath*maskPath=[UIBezierPath bezierPathWithRoundedRect:rect
byRoundingCorners:UIRectCornerAllCorners
角半径:CGSizeMake(半径,半径)];
//创建形状层并设置其路径
CAShapeLayer*maskLayer=[CAShapeLayer层];
maskLayer.frame=rect;
maskLayer.path=maskPath.CGPath;
//将新创建的形状层设置为视图层的遮罩
self.layer.mask=maskLayer;
//给边界
//为边框创建路径
UIBezierPath*borderPath=[UIBezierPath bezierPathWithRoundedRect:rect
byRoundingCorners:UIRectCornerAllCorners
角半径:CGSizeMake(半径,半径)];
//创建形状层并设置其路径
NSString*layerName=@“ig\U border\U layer”;
CAShapeLayer*borderLayer=(CAShapeLayer*)[[self.layer sublayers]filteredarrayingpredicate:[NSPredicate predicateWithFormat:@“name=%@”,layerName]]firstObject];
如果(!边界层){
边界层=[CAShapeLayer layer];
[边界层集合名:层名称];
//添加此层以提供边界。
[[self layer]addSublayer:borderLayer];
}
borderLayer.frame=rect;
borderLayer.path=borderPath.CGPath;
borderLayer.strokeColor=[UIColor whiteColor].CGColor;
borderLayer.fillColor=[UIColor clearColor].CGColor;
borderLayer.lineWidth=borderWidth;
}
@结束
比CRDave的答案更重要
我必须从Swift翻译,所以我想我应该继续并发布翻译:
extension UIView {
func giveBorderWithCornerRadius(cornerRadius r: CGFloat, borderColor c: UIColor, strokeWidth w: CGFloat) {
let rect = self.bounds
let maskPath = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: r, height: r))
let maskLayer = CAShapeLayer()
maskLayer.frame = rect
maskLayer.path = maskPath.cgPath
self.layer.mask = maskLayer
let borderPath = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: r, height: r))
let layerName = "border_layer"
var borderLayer: CAShapeLayer? = self.layer.sublayers?.filter({ (c) -> Bool in
if c.name == layerName {
return true
} else {
return false
}
}).first as? CAShapeLayer
if borderLayer == nil {
borderLayer = CAShapeLayer()
borderLayer!.name = layerName
self.layer.addSublayer(borderLayer!)
}
borderLayer!.frame = rect
borderLayer!.path = borderPath.cgPath
borderLayer!.strokeColor = c.cgColor
borderLayer!.fillColor = UIColor.clear.cgColor
borderLayer!.lineWidth = w
}
}
我是从
layoutSubviews()
调用该方法的,当borderWith也是一个整数时,它是否会出现故障?为了测试,我尝试了borderWidth 1.5、2.0、2.5和3.0,但我得到了所有相同的故障。黑色细线不是我给出的边界。请参见编辑的代码。我给第二张图片加上白色粗边框,给第一张图片加上灰色边框。这是我的问题。这是一个很好的解决方案。我遇到了一个奇怪的问题,当我用图层.拐角半径
四舍五入的时候,我用你贴的代码片段修复了这个问题。谢谢您忘记使用borderColor参数;)@KamilNomtek.com borderLayer.strokeColor=[UIColor whiteColor].CGColor;是指边框颜色。是的!非常感谢。我将发布这个答案的快速版本。
extension UIView {
func giveBorderWithCornerRadius(cornerRadius r: CGFloat, borderColor c: UIColor, strokeWidth w: CGFloat) {
let rect = self.bounds
let maskPath = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: r, height: r))
let maskLayer = CAShapeLayer()
maskLayer.frame = rect
maskLayer.path = maskPath.cgPath
self.layer.mask = maskLayer
let borderPath = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: r, height: r))
let layerName = "border_layer"
var borderLayer: CAShapeLayer? = self.layer.sublayers?.filter({ (c) -> Bool in
if c.name == layerName {
return true
} else {
return false
}
}).first as? CAShapeLayer
if borderLayer == nil {
borderLayer = CAShapeLayer()
borderLayer!.name = layerName
self.layer.addSublayer(borderLayer!)
}
borderLayer!.frame = rect
borderLayer!.path = borderPath.cgPath
borderLayer!.strokeColor = c.cgColor
borderLayer!.fillColor = UIColor.clear.cgColor
borderLayer!.lineWidth = w
}
}