iOS

How to Create Top/Bottom Rounded Corners for Views and Buttons


We are launching a new series of tutorials to answer some of the common questions. The questions can be simple ones from beginners and tough ones that require some works. One of the questions is:

I know how to create rounded corners of a view or button. But what if I just want to create a view with top/bottom rounded corners only? How can I do it in Swift?

Okay, let’s revisit how you create rounded corners for a view. Apple has made it very easy to create views with rounded corner. All you need to do is set the cornerRadius property of a view’s layer and set clipsToBounds to true. Here is the code snippet:

To visualize the implementation, you can create a Playgrounds project and fill in the code like this:

If you switch to the Assistant editor mode, you should see the view rendered like this. The view in yellow has rounded corners.

That’s pretty straightforward. All the corners are rounded. But what if you don’t want to round all the corners? Say, you just want to round the top corners.

Using maskedCorners on iOS 11

In iOS 11, Apple introduced a new property named maskedCorners for the Core Animation layer (CALayer). This property is of the type CACornerMask, which has 4 possible values:

  • layerMaxXMaxYCorner – lower right corner
  • layerMaxXMinYCorner – top right corner
  • layerMinXMaxYCorner – lower left corner
  • layerMinXMinYCorner – top left corner

By default, the value of maskedCorners is set to display all the four corners. Now, let’s say you just want to round the top corners. You can set maskedCorners to the following:

If you change the roundCorners method like below, you will only round the top corners of the view in yellow.

Using Bezier Path on iOS 10 (or lower)

The catch of this approach is that it supports iOS 11 (or up) only. If your app needs to support lower version of iOS, you can’t use the maskedCorners property.

Here is an alternate solution. Instead of using maskedCorners, we use UIBezierPath to create a rounded rectangular path. The initialization of UIBezierPath allows us to specify the corners we want to round like this:

With the path, we can create a shape layer as a mask. Update the roundCorners method like this:

We create a mask with top rounded corners and then set to the mask property of the view’s layer to mask the content. This is how we round a specific corner of a view or button on iOS 10 or lower.

But please take note that the rendering occurs after the view is appeared. Therefore, you have to call the roundCorners method in viewDidAppear() or viewDidLayoutSubviews():

The result will look like this:

Animating Corners

Some readers also wondered how to animate the corners. You can use the UIView animation or the new UIViewPropertyAnimator to animate the changes.

For example, you want to animate the corners when a user taps the square view. You can first register the tap recognizer in viewDidLoad():

And then create the animateCornerChange method like this:

In the code above, we use UIViewPropertyAnimator to create the animation. Alternatively, you can use the standard UIView animation to perform the change:

If you’ve updated the code in your Playground project, tapping the view will activate the animation.

That’s it for this tutorial. Stay tuned. We’ll have more articles to come. If you have any thoughts on this new series, please feel free to leave me comment below.

iOS
Enhance Your Simple Table App With Property List
iOS
How to Use UIPageViewController to Build Tutorial Screens
iOS
A Beginner’s Guide to SiriKit in Swift
  • David Bala

    David BalaDavid Bala

    Author Reply

    Nice tutorial! But this needs to be fixed.

    self.view.cornerRadius = 20.0
    self.view.clipToBounds = true

    It should be

    self.view.layer.cornerRadius = 20.0
    self.view.layer.clipToBounds = true

    Anyway good job!


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      Thanks! Just fixed the typo. Btw, the clipToBounds is a property of the view object.

      self.view.layer.cornerRadius = 20.0
      self.view.clipToBounds = true


  • mbeaty

    mbeatymbeaty

    Author Reply

    Why was my last comment “detected as spam”??


  • Simon Ng

    Simon NgSimon Ng

    Author Reply

    Thanks for the feedback. What’s the problem of code selection on Safari? For Disqus comments, it’s probably due to a WordPress plugin we used. There is a delay in loading the comment section, but it should work on Safari. Anyway, let me see if we should use another plugin.


  • Aashish Nagar

    This is really interesting. I want to follow this series. How to do that.


  • R_A_Chalmers

    Excellent. Don’t get any more complex than this, and you’ve got it.
    Simple and to the point.


Shares