Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 带边框的拐角半径:边框周围出现故障_Ios_Objective C_Calayer - Fatal编程技术网

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
    }
}