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

SwiftTextviewRounded Corners

Swift Problem Overview


How to set corner radius only only bottom-left, bottom-right, and top-left corners of a textview?

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)

this code creates two rects. I dont know why.

Swift Solutions


Solution 1 - Swift

(swift 4/iOS 11) Just simply say for bottom:

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

for Up:

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

in your case:

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

Hope this help :)

Solution 2 - Swift

You just need to mask the layer as shown below:

For Swift 3:

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

Lower Version:

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

Solution 3 - Swift

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

Use like this

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

Solution 4 - Swift

A better answer for both iOS 11 and iOS 10 bottom corner would be

 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
  }

in case this didnt work on iOS 10 and below, try running the code in viewDidLayoutSubviews() of your viewcontroller class like this

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
}

Solution 5 - Swift

Swift 4+

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

Top right

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

Top left

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

Bottom right

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

Bottom left

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

OR

Multiple corners at the same time

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
}

How to use

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

Solution 6 - Swift

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

Output :

enter image description here

extension on UIView Swift 4 : Reference Link

Solution 7 - Swift

Here is an extension for 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
    
   }

 }

Usage:-

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

Swift 5+

view.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner]

Solution 8 - Swift

For subview & POPUPs [Swift 5]

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

output:

enter image description here

Solution 9 - Swift

  1. Add RoundedCornerView.swift file to your project

  2. Add an UIView to your ViewController

  3. Change Custom Class in Identity Inspector to RoundedCornerView

  4. Go to Attribute Inspector pick Corner Radius (CGFloat) and On the corners you want rounded.

rounded corner view

> 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

Solution 10 - Swift

The best solution I could come up with all of the above solution is this.

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

I believe that this way the implementation is easy while selecting the sides.

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

Solution 11 - Swift

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

}

Solution 12 - Swift

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZeptView Question on Stackoverflow
Solution 1 - SwiftFabioView Answer on Stackoverflow
Solution 2 - SwiftShailesh ChandavarView Answer on Stackoverflow
Solution 3 - SwiftMuseer Ahamad AnsariView Answer on Stackoverflow
Solution 4 - Swiftknig_TView Answer on Stackoverflow
Solution 5 - SwiftRashid LatifView Answer on Stackoverflow
Solution 6 - SwiftBhadreshView Answer on Stackoverflow
Solution 7 - SwiftChathuranga SilvaView Answer on Stackoverflow
Solution 8 - SwiftNSMohammadView Answer on Stackoverflow
Solution 9 - Swiftkazi.munshimunView Answer on Stackoverflow
Solution 10 - Swiftkshitiz_7View Answer on Stackoverflow
Solution 11 - SwiftLuan Si HoView Answer on Stackoverflow
Solution 12 - SwiftHarshil KotechaView Answer on Stackoverflow