Layer.corner radius top left on storyboard not working

Starting from Xcode 6, you can build custom UI and have it rendered real time in Storyboard / XIB / Interface builder.

We are going to create an UIView with rounded corners and borders in this post. First, create a UIView subclass, I name it as 'RoundedCornerView'

Layer.corner radius top left on storyboard not working
Layer.corner radius top left on storyboard not working

And add the following cornerRadius attribute to the newly created subclass file.

RoundedCornerView.swift

import UIKit
class RoundedCornerView: UIView {
    // if cornerRadius variable is set/changed, change the corner radius of the UIView
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }
}

The above snippet initialize cornerRadius variable to 0 and any change on its value (didSet) will update the view layer cornerRadius and masksToBounds boolean if the cornerRadius is larger than 0.

The @IBInspectable keyword in front of the variable lets you set the value of cornerRadius in Interface builder!

Since @IBInspectable is based on User-defined runtime attributes, the variable types it support are also same as the runtime attributes : Boolean, Numbers (NSNumber, double, CGFloat etc), String, CGPoint, CGSize, CGRect, UIColor (Not CGColor), UIImage and also NSRange.

Layer.corner radius top left on storyboard not working

Select your desired view in interface builder, set the class to RoundedCornerView.

Layer.corner radius top left on storyboard not working

Now select Attribute Inspector tab, you should see the corner radius attribute there, Xcode even auto convert your camelcased variable name to proper format!

Layer.corner radius top left on storyboard not working

You can now set the corner radius of the view in Interface Builder, but the view still looks square after setting the corner radius to 40, what did we miss? 🤔

You need to add @IBDesignable on top of the class definition to tell Xcode that it needs to render the view properties directly in the Interface builder.

RoundedCornerView.swift

import UIKit
@IBDesignable
class RoundedCornerView: UIView {
...
}

After adding @IBDesignable , open the interface builder again, you should see a rounded corner view now wew :

Layer.corner radius top left on storyboard not working

Praise rounded corners, now you can do the same for borders :

RoundedCornerView.swift

import UIKit
@IBDesignable
class RoundedCornerView: UIView {
    // if cornerRadius variable is set/changed, change the corner radius of the UIView
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }
    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    @IBInspectable var borderColor: UIColor? {
        didSet {
            layer.borderColor = borderColor?.cgColor
        }
    }
}

Result :

Layer.corner radius top left on storyboard not working

You can download the sample Swift project here

Tired of fighting with Auto Layout constraints? Why is it so hard to make a layout to work?! Would using code for UI and constraints make it easier? (No, not really)

If you want to understand Auto Layout fundamentally (instead of just following youtube tutorials implementing a very specific layout which might not apply to your app), check out my book Making Sense of Auto Layout, with practical case study!

You should update the mask in the override of layoutSubviews. As the constraints update the frame of the view, layoutSubviews is called, so that’s the right place to update the mask.


As an aside, I’d discourage the use of awakeFromNib to configure the view. It works fine if you use storyboard, but programmatically created views won’t call this. If you do want to configure the view when it’s created, it’s better to put the code in some private configuration method which is called by init(frame:) and init(coder:). That way it works for both storyboards and programmatically created views.

I might also suggest observers on the inspectable properties, to trigger the update of the corner rounding. You want the corner rounding to update automatically if you change these properties.


Thus:

@IBDesignable
public class RoundedView: UIView {
    @IBInspectable public var topLeft: Bool = false      { didSet { setNeedsLayout() } }
    @IBInspectable public var topRight: Bool = false     { didSet { setNeedsLayout() } }
    @IBInspectable public var bottomLeft: Bool = false   { didSet { setNeedsLayout() } }
    @IBInspectable public var bottomRight: Bool = false  { didSet { setNeedsLayout() } }
    @IBInspectable public var cornerRadius: CGFloat = 0  { didSet { setNeedsLayout() } }
    public override func layoutSubviews() {
        super.layoutSubviews()
        var options = UIRectCorner()
        if topLeft     { options.formUnion(.topLeft) }
        if topRight    { options.formUnion(.topRight) }
        if bottomLeft  { options.formUnion(.bottomLeft) }
        if bottomRight { options.formUnion(.bottomRight) }
        let path = UIBezierPath(roundedRect: bounds,
                                byRoundingCorners: options,
                                cornerRadii: CGSize(width: cornerRadius, height: cornerRadius))
        let maskLayer = CAShapeLayer()
        maskLayer.path = path.cgPath
        layer.mask = maskLayer
    }
}


Or, alternatively, if targeting iOS 11 and later, we can let CoreAnimation do the rounding:

@IBDesignable
public class RoundedView: UIView {
    @IBInspectable public var topLeft: Bool = false      { didSet { updateCorners() } }
    @IBInspectable public var topRight: Bool = false     { didSet { updateCorners() } }
    @IBInspectable public var bottomLeft: Bool = false   { didSet { updateCorners() } }
    @IBInspectable public var bottomRight: Bool = false  { didSet { updateCorners() } }
    @IBInspectable public var cornerRadius: CGFloat = 0  { didSet { updateCorners() } }
    public override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        updateCorners()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        updateCorners()
    }
}
private extension RoundedView {
    func updateCorners() {
        var corners = CACornerMask()
        if topLeft     { corners.formUnion(.layerMinXMinYCorner) }
        if topRight    { corners.formUnion(.layerMaxXMinYCorner) }
        if bottomLeft  { corners.formUnion(.layerMinXMaxYCorner) }
        if bottomRight { corners.formUnion(.layerMaxXMaxYCorner) }
        layer.maskedCorners = corners
        layer.cornerRadius = cornerRadius
    }
}

The nice thing about this latter approach is that CoreAnimation will honor our corner rounding if we happen to be animating the frame of the view:

Layer.corner radius top left on storyboard not working

If you use the aforementioned layoutSubviews approach, then you have to manage the animation manually (e.g. with

@IBDesignable
public class RoundedView: UIView {
    @IBInspectable public var topLeft: Bool = false      { didSet { updateCorners() } }
    @IBInspectable public var topRight: Bool = false     { didSet { updateCorners() } }
    @IBInspectable public var bottomLeft: Bool = false   { didSet { updateCorners() } }
    @IBInspectable public var bottomRight: Bool = false  { didSet { updateCorners() } }
    @IBInspectable public var cornerRadius: CGFloat = 0  { didSet { updateCorners() } }
    public override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        updateCorners()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        updateCorners()
    }
}
private extension RoundedView {
    func updateCorners() {
        var corners = CACornerMask()
        if topLeft     { corners.formUnion(.layerMinXMinYCorner) }
        if topRight    { corners.formUnion(.layerMaxXMinYCorner) }
        if bottomLeft  { corners.formUnion(.layerMinXMaxYCorner) }
        if bottomRight { corners.formUnion(.layerMaxXMaxYCorner) }
        layer.maskedCorners = corners
        layer.cornerRadius = cornerRadius
    }
}

0).

How do you change the corner radius on a storyboard?

Select the view that you want to round and open its Identity Inspector. In the User Defined Runtime Attributes section, add the following two entries: Key Path: layer. cornerRadius , Type: Number, Value: (whatever radius you want)

How to set corner radius for top in Swift?

func roundCorners(cornerRadius:.

let path = UIBezierPath(roundedRect. bounds, byRoundingCorners: [. topLeft, . topRight], cornerRadii: CGSize(width: cornerRadius, height: cornerRadius)) let maskLayer = CAShapeLayer..

maskLayer. frame = self. bounds. maskLayer. path = path. cgPath..

self. layer. mask = maskLayer. }.

How do you give a border radius to only the left side?

CSS Syntaxborder-top-left-radius: length|% [length|%]|initial|inherit; Note: If you set two values, the first one is for the top border, and the second one for the left border. If the second value is omitted, it is copied from the first.

What is top

The border-top-left-radius CSS property rounds the top-left corner of an element by specifying the radius (or the radius of the semi-major and semi-minor axes) of the ellipse defining the curvature of the corner.