如何仅设置左下角、右下角和左上角的图层角半径?

How to set layer cornerRadius for only bottom-left, bottom-right, and top-left corner?

如何只设置文本视图的左下角、右下角和左上角的圆角半径?

let rectShape = CAShapeLayer()
rectShape.backgroundColor = UIColor.redColor().CGColor
rectShape.bounds = messages.frame
rectShape.position = messages.center
rectShape.path = UIBezierPath(roundedRect: messages.bounds, byRoundingCorners: .BottomLeft | .TopRight, cornerRadii: CGSize(width: 20, height: 20)).CGPath

messages.layer.addSublayer(rectShape)

此代码创建两个矩形。不知道为什么。

您只需如下图所示遮罩图层即可:

对于Swift3:

let rectShape = CAShapeLayer()
rectShape.bounds = self.myView.frame
rectShape.position = self.myView.center
rectShape.path = UIBezierPath(roundedRect: self.myView.bounds, byRoundingCorners: [.bottomLeft , .bottomRight , .topLeft], cornerRadii: CGSize(width: 20, height: 20)).cgPath

self.myView.layer.backgroundColor = UIColor.green.cgColor
//Here I'm masking the textView's layer with rectShape layer
self.myView.layer.mask = rectShape

低版本:

let rectShape = CAShapeLayer()
rectShape.bounds = self.myView.frame
rectShape.position = self.myView.center
rectShape.path = UIBezierPath(roundedRect: self.myView.bounds, byRoundingCorners: .BottomLeft | .BottomRight | .TopLeft, cornerRadii: CGSize(width: 20, height: 20)).CGPath

self.myView.layer.backgroundColor = UIColor.greenColor().CGColor
//Here I'm masking the textView's layer with rectShape layer
self.myView.layer.mask = rectShape

Swift 3

extension UIView {
    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
  }
}

这样使用

YourView.roundCorners([.topLeft, .bottomLeft], radius: 10)

(swift 4/iOS 11) 就简单说下:

yourView.clipsToBounds = true 
yourView.layer.cornerRadius = 10
yourView.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner]

向上:

yourView.clipsToBounds = true 
yourView.layer.cornerRadius = 10
yourView.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]

你的情况:

yourView.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]

希望对您有所帮助:)

对于 iOS 11 和 iOS 10 底角更好的答案是

 if #available(iOS 11.0, *){
        view.clipsToBounds = true
        view.layer.cornerRadius = 10
        view.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner]
    }else{
       let rectShape = CAShapeLayer()
       rectShape.bounds = view.frame
       rectShape.position = view.center
       rectShape.path = UIBezierPath(roundedRect: view.bounds,    byRoundingCorners: [.bottomLeft , .bottomRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
      view.layer.backgroundColor = UIColor.green.cgColor
      view.layer.mask = rectShape
  }

如果这在 iOS 10 及以下版本上不起作用,请尝试 运行 您的 viewcontroller class 的 viewDidLayoutSubviews() 中的代码,像这样

override func viewDidLayoutSubviews() {
    if #available(iOS 11.0, *){
    }else{
       let rectShape = CAShapeLayer()
       rectShape.bounds = view.frame
       rectShape.position = view.center
       rectShape.path = UIBezierPath(roundedRect: view.bounds,    byRoundingCorners: [.bottomLeft , .bottomRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
       view.layer.backgroundColor = UIColor.green.cgColor
       view.layer.mask = rectShape
}

issue solved right top and right bottom work now

Tested code in iOS 9 , 10 , 11 version

 extension UIView {
        func roundCorners(_ corners:UIRectCorner,_ cormerMask:CACornerMask, radius: CGFloat) {
            if #available(iOS 11.0, *){
                self.clipsToBounds = false
                self.layer.cornerRadius = radius
                self.layer.maskedCorners = cormerMask
            }else{
                let rectShape = CAShapeLayer()
                rectShape.bounds = self.frame
                rectShape.position = self.center
                rectShape.path = UIBezierPath(roundedRect: self.bounds,    byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)).cgPath
                self.layer.mask = rectShape
            }
        }
        
    }

Swift 4

override func viewDidLoad() {
    let topRight = UIView(frame: CGRect(x: 120, y: 200, width: 120, height: 120))
    topRight.roundedTop()
    topRight.backgroundColor = .red
    self.view.center = topRight.center
    self.view.addSubview(topRight)
    super.viewDidLoad()
}

输出:

UIView 上的扩展 Swift 4:Reference Link

这是 iOS 11+

的扩展
 import Foundation
 import UIKit

 extension UIView {

   func roundCorners(_ corners: CACornerMask, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
       self.layer.maskedCorners = corners
       self.layer.cornerRadius = radius
       self.layer.borderWidth = borderWidth
       self.layer.borderColor = borderColor.cgColor
    
   }

 }

用法:-

self.yourView.roundCorners([.layerMaxXMaxYCorner, .layerMaxXMinYCorner], radius: 20.0, borderColor: UIColor.green, borderWidth: 1)

Swift 5+

view.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner]
  1. 将 RoundedCornerView.swift 文件添加到您的项目
  2. 将 UIView 添加到您的 ViewController
  3. 将 Identity Inspector 中的自定义 Class 更改为 RoundedCornerView
  4. 转到 Attribute Inspector 选择角半径 (CGFloat) 并在您想要圆角的角上。

RoundedCornerView.swift

import UIKit

@IBDesignable
class RoundedCornerView: UIView {

    var cornerRadiusValue : CGFloat = 0
    var corners : UIRectCorner = []

    @IBInspectable public var cornerRadius : CGFloat {
        get {
            return cornerRadiusValue
        }
        set {
            cornerRadiusValue = newValue
        }
    }

    @IBInspectable public var topLeft : Bool {
        get {
            return corners.contains(.topLeft)
        }
        set {
            setCorner(newValue: newValue, for: .topLeft)
        }
    }

    @IBInspectable public var topRight : Bool {
        get {
            return corners.contains(.topRight)
        }
        set {
            setCorner(newValue: newValue, for: .topRight)
        }
    }

    @IBInspectable public var bottomLeft : Bool {
        get {
            return corners.contains(.bottomLeft)
        }
        set {
            setCorner(newValue: newValue, for: .bottomLeft)
        }
    }

    @IBInspectable public var bottomRight : Bool {
        get {
            return corners.contains(.bottomRight)
        }
        set {
            setCorner(newValue: newValue, for: .bottomRight)
        }
    }

    func setCorner(newValue: Bool, for corner: UIRectCorner) {
        if newValue {
            addRectCorner(corner: corner)
        } else {
            removeRectCorner(corner: corner)
        }
    }

    func addRectCorner(corner: UIRectCorner) {
        corners.insert(corner)
        updateCorners()
    }

    func removeRectCorner(corner: UIRectCorner) {
        if corners.contains(corner) {
            corners.remove(corner)
            updateCorners()
        }
    }

    func updateCorners() {
        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: cornerRadiusValue, height: cornerRadiusValue))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.layer.mask = mask
    }

}

github link : RoundedCornerView

extension UIView {

func roundCorners(_ corners: CACornerMask, radius: CGFloat) {
    if #available(iOS 11, *) {
        self.layer.cornerRadius = radius
        self.layer.maskedCorners = corners
    } else {
        var cornerMask = UIRectCorner()
        if(corners.contains(.layerMinXMinYCorner)){
            cornerMask.insert(.topLeft)
        }
        if(corners.contains(.layerMaxXMinYCorner)){
            cornerMask.insert(.topRight)
        }
        if(corners.contains(.layerMinXMaxYCorner)){
            cornerMask.insert(.bottomLeft)
        }
        if(corners.contains(.layerMaxXMaxYCorner)){
            cornerMask.insert(.bottomRight)
        }
        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: cornerMask, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.layer.mask = mask
    }
}

}

对于子视图和 POPUP [Swift 5]

override func layoutSublayers(of layer: CALayer) {
    searchBarPopup.clipsToBounds = true
    searchBarPopup.layer.cornerRadius = 10
    searchBarPopup.layer.maskedCorners = [ .layerMaxXMinYCorner, .layerMinXMinYCorner]
}

输出:

Swift 4+

func roundCorners(with CACornerMask: CACornerMask, radius: CGFloat) {
    self.layer.cornerRadius = radius
    self.layer.maskedCorners = [CACornerMask]
}

右上角

roundCorners(with: [.layerMinXMinYCorner], radius: 20)

左上角

roundCorners(with: [.layerMaxXMinYCorner], radius: 20)

右下角

roundCorners(with: [.layerMinXMaxYCorner], radius: 20)

左下角

roundCorners(with: [.layerMaxXMaxYCorner], radius: 20)

同时多个角

func roundedCorners(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
    layer.mask = mask
}

如何使用

roundedCorners(corners: [.topLeft, .topRight], radius: 20)

我能想出以上所有解决方案的最佳解决方案是这个。

extension UIView {
    func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
        if #available(iOS 11, *) {
            var cornerMask = CACornerMask()
            if(corners.contains(.topLeft)){
                cornerMask.insert(.layerMinXMinYCorner)
            }
            if(corners.contains(.topRight)){
                cornerMask.insert(.layerMaxXMinYCorner)
            }
            if(corners.contains(.bottomLeft)){
                cornerMask.insert(.layerMinXMaxYCorner)
            }
            if(corners.contains(.bottomRight)){
                cornerMask.insert(.layerMaxXMaxYCorner)
            }
            self.layer.cornerRadius = radius
            self.layer.maskedCorners = cornerMask

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

我相信这种选择边的方式实现起来很容易。

view.roundCorners([.bottomLeft, .bottomRight, .topLeft], radius: 16)