Create a rectangle with just two rounded corners in swift?

In Swift 2.3 you could do so by

let maskPath = UIBezierPath(roundedRect: anyView.bounds,
            byRoundingCorners: [.BottomLeft, .BottomRight],
            cornerRadii: CGSize(width: 10.0, height: 10.0))

let shape = CAShapeLayer()
shape.path = maskPath.CGPath
view.layer.mask = shape

In Objective-C you could use the UIBezierPath class method

bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:

example implementation-

// set the corner radius to the specified corners of the passed container
- (void)setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners
{
    UIBezierPath *rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds
                                                  byRoundingCorners:corners
                                                        cornerRadii:CGSizeMake(10.0, 10.0)];
    CAShapeLayer *shape = [[CAShapeLayer alloc] init];
    [shape setPath:rounded.CGPath];
    view.layer.mask = shape;
}

and call the above method as-

[self setMaskTo:anyView byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight];

Swift 3 - Useful UIView extension when you need to round specific corners of some views:

extension UIView {
  func round(corners: UIRectCorner, radius: CGFloat) {
    let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
    let mask = CAShapeLayer()
    mask.path = path.cgPath
    self.layer.mask = mask
  }
}

then just use it like this:

someView.round(corners: [.topLeft, .topRight], radius: 5)

Swift 4+, iOS 11+

If you already have a UIView named myView referenced as an IBOutlet, try adding the following two lines in ViewDidLoad() or wherever it's being loaded:

myView.layer.cornerRadius = 10
myView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]

You can change the array [] to any combination of MinX, MinY, MaxX, and MaxY to select the desired corners. The above example rounds the bottom two corners.

This is just another approach, can be a bit simpler depending on your design.


Update: See this answer below for Swift 4 / iOS 11 which is much, much easier


Here's a quick Swift 3 extension you can use to do rounding and optional borders.

Note: if you're using autolayout, you may need to call this in one of the view lifecycle callbacks like viewDidLayoutSubviews or layoutSubviews after the view has been constrained.

import UIKit

extension UIView {
    
    /**
     Rounds the given set of corners to the specified radius
     
     - parameter corners: Corners to round
     - parameter radius:  Radius to round to
     */
    func round(corners: UIRectCorner, radius: CGFloat) {
        _ = _round(corners: corners, radius: radius)
    }
    
    /**
     Rounds the given set of corners to the specified radius with a border
     
     - parameter corners:     Corners to round
     - parameter radius:      Radius to round to
     - parameter borderColor: The border color
     - parameter borderWidth: The border width
     */
    func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
        let mask = _round(corners: corners, radius: radius)
        addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
    }
    
    /**
     Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
     
     - parameter diameter:    The view's diameter
     - parameter borderColor: The border color
     - parameter borderWidth: The border width
     */
    func fullyRound(diameter: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
        layer.masksToBounds = true
        layer.cornerRadius = diameter / 2
        layer.borderWidth = borderWidth
        layer.borderColor = borderColor.cgColor;
    }
    
}

private extension UIView {
    
    @discardableResult func _round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer {
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.layer.mask = mask
        return mask
    }
    
    func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) {
        let borderLayer = CAShapeLayer()
        borderLayer.path = mask.path
        borderLayer.fillColor = UIColor.clear.cgColor
        borderLayer.strokeColor = borderColor.cgColor
        borderLayer.lineWidth = borderWidth
        borderLayer.frame = bounds
        layer.addSublayer(borderLayer)
    }
    
}