每个拐角的不同拐角半径Swift 3-iOS

每个拐角的不同拐角半径Swift 3-iOS,ios,swift3,cornerradius,Ios,Swift3,Cornerradius,我想在Swift-3中为视图设置不同的角半径,我可以将每个角的半径设置为相同的值,就像下面的帖子中提到的一样 有没有办法按以下格式设置角半径? 左上角半径:18 右上角半径:18 右下角半径:3 左下角半径:18您可以将默认的图层。拐角半径设置为最小值,然后将图层遮罩的边框设置为较大值 let demoView = UIView(frame: CGRect(x: 100, y: 200, width: 100, height: 100)) demoView.backgroundColor = U

我想在Swift-3中为视图设置不同的角半径,我可以将每个角的半径设置为相同的值,就像下面的帖子中提到的一样

有没有办法按以下格式设置角半径? 左上角半径:18 右上角半径:18 右下角半径:3
左下角半径:18

您可以将默认的
图层。拐角半径
设置为最小值,然后将图层遮罩的边框设置为较大值

let demoView = UIView(frame: CGRect(x: 100, y: 200, width: 100, height: 100))
demoView.backgroundColor = UIColor.red
demoView.layer.cornerRadius = 3.0

let maskPath = UIBezierPath(roundedRect: demoView.bounds,
                            byRoundingCorners: [.topLeft, .topRight, .bottomLeft],
                            cornerRadii: CGSize(width: 18.0, height: 0.0))

let maskLayer = CAShapeLayer()
maskLayer.path = maskPath.cgPath
demoView.layer.mask = maskLayer
view.addSubview(demoView)

是否要为每个角点添加唯一的角点值

是否要在此之后添加边框

我有一个解决方案如下:

首先,添加一个我制作的
UIBezierPath
扩展名:

扩展UIBezierPath{ 便利初始化(shouldldroundrect-rect:CGRect,topLeftRadius:CGSize=.zero,topLeftRadius:CGSize=.zero,bottomLeftRadius:CGSize=.zero,bottomrightdradius:CGSize=.zero){ self.init() let path=CGMutablePath() 设topLeft=rect.origin 设topRight=CGPoint(x:rect.maxX,y:rect.minY) 设bottomRight=CGPoint(x:rect.maxX,y:rect.maxY) 设bottomLeft=CGPoint(x:rect.minX,y:rect.maxY) 如果topLeftRadius!=0{ 移动路径(到:CGPoint(x:topLeft.x+topLeftRadius.width,y:topLeft.y)) }否则{ 移动路径(到:CGPoint(x:topLeft.x,y:topLeft.y)) } 如果topRightRadius!=0{ path.addLine(to:CGPoint(x:topRight.x-topRightRadius.width,y:topRight.y)) 添加曲线(到:CGPoint(x:topRight.x,y:topRight.y+topRightRadius.height),控制1:CGPoint(x:topRight.x,y:topRight.y),控制2:CGPoint(x:topRight.x,y:topRight.y+topRightRadius.height)) }否则{ addLine(to:CGPoint(x:topRight.x,y:topRight.y)) } 如果bottomRightRadius!=0{ addLine(to:CGPoint(x:bottomRight.x,y:bottomRight.y-bottomRightRadius.height)) 添加曲线(到:CGPoint(x:bottomRight.x-bottomRightRadius.width,y:bottomRight.y),控件1:CGPoint(x:bottomRight.x,y:bottomRight.y),控件2:CGPoint(x:bottomRight.x-bottomRightRadius.width,y:bottomRight.y)) }否则{ addLine(to:CGPoint(x:bottomRight.x,y:bottomRight.y)) } 如果bottomLeftRadius!=0{ addLine(to:CGPoint(x:bottomLeft.x+bottomLeftRadius.width,y:bottomLeft.y)) 添加曲线(到:CGPoint(x:bottomLeft.x,y:bottomLeft.y-bottomLeftRadius.height),控件1:CGPoint(x:bottomLeft.x,y:bottomLeftRadius.y),控件2:CGPoint(x:bottomLeft.x,y:bottomLeft.y-bottomLeftRadius.height)) }否则{ addLine(to:CGPoint(x:bottomLeft.x,y:bottomLeft.y)) } 如果topLeftRadius!=0{ addLine(to:CGPoint(x:topLeft.x,y:topLeft.y+topLeftRadius.height)) 添加曲线(到:CGPoint(x:topLeft.x+topLeftRadius.width,y:topLeft.y),控件1:CGPoint(x:topLeft.x,y:topLeft.y),控件2:CGPoint(x:topLeft.x+topLeftRadius.width,y:topLeft.y)) }否则{ addLine(to:CGPoint(x:topLeft.x,y:topLeft.y)) } path.closeSubpath() cgPath=path } } 然后,添加此
ui视图
扩展名:

扩展UIView{ func圆角(左上:CGFloat=0,右上:CGFloat=0,左下:CGFloat=0,右下:CGFloat=0){/(左上:CGFloat,右上:CGFloat,左下:CGFloat,右下:CGFloat){ 设topLeftRadius=CGSize(宽度:topLeft,高度:topLeft) 设topRightRadius=CGSize(宽度:topRight,高度:topRight) 让bottomLeftRadius=CGSize(宽度:bottomLeft,高度:bottomLeft) 让bottomRightRadius=CGSize(宽度:bottomRight,高度:bottomRight) 设maskPath=UIBezierPath(shouldRoundRect:bounds,topLeftRadius:topLeftRadius,topRightRadius:topRightRadius,bottomLeftRadius:bottomLeftRadius,bottomRightRadius:bottomRightRadius) let shape=CAShapeLayer() shape.path=maskPath.cgPath layer.mask=形状 } } 最后,调用方法

myView.roundCorners(左上:10,右上:20,左下:30,右下:40)
显然,layer.borderRadius无法正常工作,因此请使用
CAShapeLayer
和以前创建的路径创建一个边框

let borderLayer=CAShapeLayer()
borderLayer.path=(myView.layer.mask!as!CAShapeLayer).path!//重用贝塞尔路径
borderLayer.strokeColor=UIColor.red.cgColor
borderLayer.fillColor=UIColor.clear.cgColor
borderLayer.lineWidth=5
borderLayer.frame=myView.bounds
myView.layer.addSublayer(边界层)

瞧!

一个基于@Kirill Dobryakov的略微改进和简化的答案。当你看到曲线时,你知道它不是理想的圆形(例如,查看侧面40和半径20),曲线会留下非常小但明显的不规则。我甚至不知道这是怎么可能的,但无论如何,最可靠的方法是使用圆弧,它可以形成理想的圆角,同时也是一个
@ibdesignable
组件:

extension UIBezierPath {

    convenience init(shouldRoundRect rect: CGRect, topLeftRadius: CGFloat, topRightRadius: CGFloat, bottomLeftRadius: CGFloat, bottomRightRadius: CGFloat){

        self.init()

        let path = CGMutablePath()

        let topLeft = rect.origin
        let topRight = CGPoint(x: rect.maxX, y: rect.minY)
        let bottomRight = CGPoint(x: rect.maxX, y: rect.maxY)
        let bottomLeft = CGPoint(x: rect.minX, y: rect.maxY)

        if topLeftRadius != 0 {
            path.move(to: CGPoint(x: topLeft.x + topLeftRadius, y: topLeft.y))
        } else {
            path.move(to: topLeft)
        }

        if topRightRadius != 0 {
            path.addLine(to: CGPoint(x: topRight.x - topRightRadius, y: topRight.y))
            path.addArc(tangent1End: topRight, tangent2End: CGPoint(x: topRight.x, y: topRight.y + topRightRadius), radius: topRightRadius)
        }
        else {
            path.addLine(to: topRight)
        }

        if bottomRightRadius != 0 {
            path.addLine(to: CGPoint(x: bottomRight.x, y: bottomRight.y - bottomRightRadius))
            path.addArc(tangent1End: bottomRight, tangent2End: CGPoint(x: bottomRight.x - bottomRightRadius, y: bottomRight.y), radius: bottomRightRadius)
        }
        else {
            path.addLine(to: bottomRight)
        }

        if bottomLeftRadius != 0 {
            path.addLine(to: CGPoint(x: bottomLeft.x + bottomLeftRadius, y: bottomLeft.y))
            path.addArc(tangent1End: bottomLeft, tangent2End: CGPoint(x: bottomLeft.x, y: bottomLeft.y - bottomLeftRadius), radius: bottomLeftRadius)
        }
        else {
            path.addLine(to: bottomLeft)
        }

        if topLeftRadius != 0 {
            path.addLine(to: CGPoint(x: topLeft.x, y: topLeft.y + topLeftRadius))
            path.addArc(tangent1End: topLeft, tangent2End: CGPoint(x: topLeft.x + topLeftRadius, y: topLeft.y), radius: topLeftRadius)
        }
        else {
            path.addLine(to: topLeft)
        }

        path.closeSubpath()
        cgPath = path
    }
}



@IBDesignable
open class VariableCornerRadiusView: UIView  {

    private func applyRadiusMaskFor() {
        let path = UIBezierPath(shouldRoundRect: bounds, topLeftRadius: topLeftRadius, topRightRadius: topRightRadius, bottomLeftRadius: bottomLeftRadius, bottomRightRadius: bottomRightRadius)
        let shape = CAShapeLayer()
        shape.path = path.cgPath
        layer.mask = shape
    }

    @IBInspectable
    open var topLeftRadius: CGFloat = 0 {
        didSet { setNeedsLayout() }
    }

    @IBInspectable
    open var topRightRadius: CGFloat = 0 {
        didSet { setNeedsLayout() }
    }

    @IBInspectable
    open var bottomLeftRadius: CGFloat = 0 {
        didSet { setNeedsLayout() }
    }

    @IBInspectable
    open var bottomRightRadius: CGFloat = 0 {
        didSet { setNeedsLayout() }
    }

    override open func layoutSubviews() {
        super.layoutSubviews()
        applyRadiusMaskFor()
    }
}

最好的方法是在iOS 11之后,这样看起来更平滑

 func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
        clipsToBounds = true
        layer.cornerRadius = radius
        layer.maskedCorners = CACornerMask(rawValue: corners.rawValue)
  }

对于原始答案:

请参阅此答案:与预期一样有效。非常感谢。它与border不起作用。还有吗?谢谢。我不知道为什么此答案的分数如此低。这是最好的答案。涵盖了各个方面。可以简化一点,例如,而不是
path.addLine(to:CGPoint(x:topLeft.x,y:topLeft.y))
if可以是
path.addLine(to:top:left)
和许多类似的行。答案很好,但我正在尝试应用阴影..然后阴影不应用@ArashAfsharpour@MaulikshahUIView上的阴影?或按钮?我有奇怪的行为(即,只有左上角的玉米)