目前设置UIView角落半径的"正确"方法是什么?

Gol*_*Joe 10 uiview ios swift

设置UIView角的半径可以通过以下方式完成:

  1. 设置layercornerRadius属性:

    view.layer.cornerRadius = 5;
    view.layer.masksToBounds = true;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 涂上面膜:

    func roundCorners(corners:UIRectCorner, radius: CGFloat) {
        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
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 覆盖draw(_:):

    func draw(_ rect: CGRect) {
        // Size of rounded rectangle
        let rectWidth = rect.width
        let rectHeight = rect.height
    
        // Find center of actual frame to set rectangle in middle
        let xf: CGFloat = (self.frame.width  - rectWidth)  / 2
        let yf: CGFloat = (self.frame.height - rectHeight) / 2
    
        let ctx = UIGraphicsGetCurrentContext()!
        ctx.saveGState()
    
        let rect = CGRect(x: xf, y: yf, width: rectWidth, height: rectHeight)
        let clipPath = UIBezierPath(roundedRect: rect, cornerRadius: rectCornerRadius).cgPath
    
        ctx.addPath(clipPath)
        ctx.setFillColor(rectBgColor.cgColor)
    
        ctx.closePath()
        ctx.fillPath()
        ctx.restoreGState()
    }
    
    Run Code Online (Sandbox Code Playgroud)

这些中的哪一个通常被认为是在a上实现圆角的"正确"方式,UIView符合以下标准:

  • 配置(某些角可以是圆形而其他角不是)
  • 动画(你可以动画cornerRadius变化)
  • 灵活性(它是否会破坏您已应用的第三方库或掩码)
  • 可读性(解决方案的简洁/可重用性)
  • 速度(对性能产生负面影响)

Rob*_*Rob 8

你的三个选择:

  1. 使用CALayer现有属性:这是简单角落遮罩的简单(也可能是最有效)解决方案.它也是可动画的.在iOS 11中,您可以选择蒙面角.

  2. 重新定制CAShapeLayer蒙版:如果角落蒙版不是简单的圆角,而是一些任意路径,这是很好的方法.如果frame更改(例如在layoutSubviews视图中或在viewDidLayoutSubviews控制器中),您必须小心确保更新此掩码.动画需要更多的工作.

  3. 重新定制draw(_:):这比其价值更多的工作,你可能不会享受Apple团队可能在幕后做的优化(例如,如果后续draw调用只是绘制了一部分,那么bounds你的代码重绘了整个事情,无论如何).

我建议选项1用于简单情况,如果你需要更多控制而不是选项1可以提供选项2.但是没有"最佳"方法:这取决于你需要什么以及你愿意接受多少工作.


Lad*_*d.c 7

我使用iOS 11或更低版本进行了几次测试以及我发现的最佳实践,可以围绕特定或所有角落,您可以使用下一个代码.

// Full size
CGSize vSize = [UIScreen mainScreen].bounds.size;

// Object
UIView *viewTest = [[UIView alloc] initWithFrame: CGRectMake(0, 0, vSize.width, vSize.height)];
[viewTest setAutoresizingMask: UIViewAutoresizingFlexibleHeight];
[viewTest setBackgroundColor: [UIColor grayColor]];

// maskedCorners is only available in iOS 11
if (@available(iOS 11.0, *)) {
    [viewTest setClipsToBounds: YES];
    [viewTest.layer setCornerRadius: 10];

    // Only if you want to round the left and right top corners
    [viewTest.layer setMaskedCorners: kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner];
}
else {
    // The old way used in lower version
    CAShapeLayer *shapeLayerObj = [CAShapeLayer layer];
    [shapeLayerObj setPath: [UIBezierPath bezierPathWithRoundedRect: viewTest.bounds byRoundingCorners: UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii: (CGSize){10.0, 10.}].CGPath];

    [viewTest.layer setMask: shapeLayerObj];
}
Run Code Online (Sandbox Code Playgroud)
  • 此代码修复了autoResizingMask在使用旧方法圆角时不起作用的问题.
  • 修复带有圆角的UIScrollView和对象高度的setContentSize主要的错误.

快速版本是这样的

let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 8
view.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner]
Run Code Online (Sandbox Code Playgroud)


gsk*_*yte 5

我认为这是所有内容中最全面的摘要:http://texturegroup.org/docs/corner-rounding.html

我的启发式是,如果视图不需要高性能(例如,它不在表视图单元格内),最简单的选择是使用CALayer cornerRadius.如果您需要更高级的角半径或高性能,那么最好探索其他选项.


Bru*_*eri 5

从iOS 11以上

您可以通过设置以下属性,在Identity inspector中使用用户定义的运行时属性Interface Builder

layer.cornerRadius
layer.maskedCorners
layer.masksToBounds
Run Code Online (Sandbox Code Playgroud)

根据CACornerMask文档,您可以看到该maskedCorners属性实际上是一种NSUInteger数据类型,并且可以设置以下值:

kCALayerMinXMinYCorner = 1U << 0
kCALayerMaxXMinYCorner = 1U << 1
kCALayerMinXMaxYCorner = 1U << 2
kCALayerMaxXMaxYCorner = 1U << 3
Run Code Online (Sandbox Code Playgroud)

由于您可以OR一起使用这些掩码,因此只需“计算”实际所需的结果整数。

因此,请为maskedCorners属性设置以下数字(整数)值以获取圆角:

 0 = no corner is being rounded
 1 = top left corner rounded only
 3 = top left and top right corners rounded only
 7 = top left, top right and bottom right corners rounded only
15 = all corners rounded
Run Code Online (Sandbox Code Playgroud)

示例:如果只想为UIView的左上角和右上角设置拐角半径,则可以使用以下属性:

UIView的左上角和右上角


Ale*_*una 1

我选择第一个,这是更简洁的方法,您可以在 IDE 中完成,无需代码。打开属性检查器,然后单击身份检查器并在“用户定义的运行时属性”下添加这两个属性:

在此输入图像描述

  • 但这不允许仅对某些角进行圆角化的第一个标准。 (2认同)