Search code examples
iosswiftuiviewcalayeruibezierpath

Smooth Rounded UIView Corners, Bottom Only


Here's the view I'm trying to mimic from the Mock-Ups I have to go with:

InVision Mock Up

Using the following code;

self.plusButton.layer.masksToBounds = true
let maskPathPlus = UIBezierPath(roundedRect: self.plusButton.bounds, byRoundingCorners: [.topRight, .topLeft], cornerRadii: CGSize(width: 4, height: 4))
let maskLayerPlus = CAShapeLayer()
maskLayerPlus.frame = self.plusButton.bounds
maskLayerPlus.path = maskPathPlus.cgPath
plusButton.layer.mask = maskLayerPlus

self.minusButton.layer.masksToBounds = true
self.minusButton.layer.borderColor = UIColor.init(colorLiteralRed: 0.2265625, green: 0.82421875, blue: 0.34765625, alpha: 1.0).cgColor
self.minusButton.layer.borderWidth = 1.0
let maskPathMinus = UIBezierPath(roundedRect: self.minusButton.bounds, byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 4, height: 4))
let maskLayerMinus = CAShapeLayer()
maskLayerMinus.frame = self.minusButton.bounds
maskLayerMinus.path = maskPathMinus.cgPath
minusButton.layer.mask = maskLayerMinus

I was able to achieve this:

iOS Simulator Screengrab

What can I do to smooth out those edges, as they appear to only be rounding the external edges of the view and clipping the border. I can't do a simple .cornerRadius because the top of the ( - ) and the bottom of the ( + ) need to be squared.


Solution

  • You should put the + and - buttons inside of another view and put the border on the containing view. Then you can use the cornerRadius property and this will have no effect on the bottom of the + and top of the -.

    @IBOutlet weak var upDownButton: UIView! // Contains the plus and minus buttons, constraints in storyboard
    
    self.upDownButton.layer.borderWidth = 1.0
    self.upDownButton.layer.borderColor = UIColor.init(colorLiteralRed: 0.2265625, green: 0.82421875, blue: 0.34765625, alpha: 1.0).cgColor
    self.upDownButton.layer.masksToBounds = true
    self.upDownButton.layer.cornerRadius = 4.0
    

    I used constraints to layout the +/- buttons inside their container with a "equal height" constraint with a multiplier of 0.5.

    The end result will look like this:

    enter image description here