Different cornerRadius for each corner Swift 3 - iOS

后端 未结 4 1261
刺人心
刺人心 2020-12-03 16:57

I want to set different corner radius for a view in Swift -3 , I am able to set the radius for the each corner to the same value like the one mentioned in the following post

4条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-03 17:57

    Do you want to add unique corner value for each corner?

    Do you want to add a border after that?

    I've got a solution will look like this:

    looks like this

    First, add a UIBezierPath extension I made:

    extension UIBezierPath {
        convenience init(shouldRoundRect rect: CGRect, topLeftRadius: CGSize = .zero, topRightRadius: CGSize = .zero, bottomLeftRadius: CGSize = .zero, bottomRightRadius: CGSize = .zero){
    
            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 != .zero{
                path.move(to: CGPoint(x: topLeft.x+topLeftRadius.width, y: topLeft.y))
            } else {
                path.move(to: CGPoint(x: topLeft.x, y: topLeft.y))
            }
    
            if topRightRadius != .zero{
                path.addLine(to: CGPoint(x: topRight.x-topRightRadius.width, y: topRight.y))
                path.addCurve(to:  CGPoint(x: topRight.x, y: topRight.y+topRightRadius.height), control1: CGPoint(x: topRight.x, y: topRight.y), control2:CGPoint(x: topRight.x, y: topRight.y+topRightRadius.height))
            } else {
                 path.addLine(to: CGPoint(x: topRight.x, y: topRight.y))
            }
    
            if bottomRightRadius != .zero{
                path.addLine(to: CGPoint(x: bottomRight.x, y: bottomRight.y-bottomRightRadius.height))
                path.addCurve(to: CGPoint(x: bottomRight.x-bottomRightRadius.width, y: bottomRight.y), control1: CGPoint(x: bottomRight.x, y: bottomRight.y), control2: CGPoint(x: bottomRight.x-bottomRightRadius.width, y: bottomRight.y))
            } else {
                path.addLine(to: CGPoint(x: bottomRight.x, y: bottomRight.y))
            }
    
            if bottomLeftRadius != .zero{
                path.addLine(to: CGPoint(x: bottomLeft.x+bottomLeftRadius.width, y: bottomLeft.y))
                path.addCurve(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y-bottomLeftRadius.height), control1: CGPoint(x: bottomLeft.x, y: bottomLeft.y), control2: CGPoint(x: bottomLeft.x, y: bottomLeft.y-bottomLeftRadius.height))
            } else {
                path.addLine(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y))
            }
    
            if topLeftRadius != .zero{
                path.addLine(to: CGPoint(x: topLeft.x, y: topLeft.y+topLeftRadius.height))
                path.addCurve(to: CGPoint(x: topLeft.x+topLeftRadius.width, y: topLeft.y) , control1: CGPoint(x: topLeft.x, y: topLeft.y) , control2: CGPoint(x: topLeft.x+topLeftRadius.width, y: topLeft.y))
            } else {
                path.addLine(to: CGPoint(x: topLeft.x, y: topLeft.y))
            }
    
            path.closeSubpath()
            cgPath = path
        }
    }
    

    Then, add this UIView extension:

    extension UIView{
        func roundCorners(topLeft: CGFloat = 0, topRight: CGFloat = 0, bottomLeft: CGFloat = 0, bottomRight: CGFloat = 0) {//(topLeft: CGFloat, topRight: CGFloat, bottomLeft: CGFloat, bottomRight: CGFloat) {
            let topLeftRadius = CGSize(width: topLeft, height: topLeft)
            let topRightRadius = CGSize(width: topRight, height: topRight)
            let bottomLeftRadius = CGSize(width: bottomLeft, height: bottomLeft)
            let bottomRightRadius = CGSize(width: bottomRight, height: bottomRight)
            let maskPath = UIBezierPath(shouldRoundRect: bounds, topLeftRadius: topLeftRadius, topRightRadius: topRightRadius, bottomLeftRadius: bottomLeftRadius, bottomRightRadius: bottomRightRadius)
            let shape = CAShapeLayer()
            shape.path = maskPath.cgPath
            layer.mask = shape
        }
    }
    

    Finally, call method

    myView.roundCorners(topLeft: 10, topRight: 20, bottomLeft: 30, bottomRight: 40)
    

    And add border. Apparently, layer.borderRadius won't work properly, so create a border using CAShapeLayer and previously created path.

    let borderLayer = CAShapeLayer()
    borderLayer.path = (myView.layer.mask! as! CAShapeLayer).path! // Reuse the Bezier path
    borderLayer.strokeColor = UIColor.red.cgColor
    borderLayer.fillColor = UIColor.clear.cgColor
    borderLayer.lineWidth = 5
    borderLayer.frame = myView.bounds
    myView.layer.addSublayer(borderLayer)
    

    Voila!

提交回复
热议问题