Make App Pie

Training for Developers and Artists

Make Round Buttons and UIViews

In the good old days, Apple used a lot of rounded corner buttons. Many developers use several images to get the effect of round buttons. The CALayer of UIButton does have a feature for you to easily get rounded corners, and even circular buttons.
Download the code from GitHub and open the starter file. It doesn’t do much but look pretty. Head over to the storyboard and you’ll see it is a series of rectangular buttons in a stack view and one square button. I made outlets for the square button and for the stack view, but in this case not for the individual buttons.
Head over to the ViewController class. We are going to do all our work today in didLayoutSubviews. You’ll see why shortly. There is one method to make a rounded corner, cornerRadius. You set the radius in points to describe the rounded area. For example I can make the square button have some rounded edges like this:

squareButton.layer.cornerRadius = 15.0

Set the simulator to iPhone XR and run. You will find rounded corners on the order button

.

Stop the app.
Rounded corners work even better as a relative size to the smallest dimension, usually the height. I can change this line to

squareButton.layer.cornerRadius = squareButton.frame.height * 0.20

This is also why I’m doing this in viewDidLayoutSubviews. When using auto layout, I don’t know the height until here. Run and the button is rounded 20% of the height.


You can also consistently handle buttons in a stack view.
I’ll make a for loop to iterate through all the arranged sub views in the stack view.

for view in stackView.arrangedSubviews{
}

I’ll find the buttons in the stack view by casting the view to a UIButton.

if let button = view as? UIButton{
}

If they are buttons, I’ll round the corners 20%

button.layer.cornerRadius = button.frame.height * 0.20

Run this and you get rounded corners on your stack view buttons.

I like perfectly rounded ends, and you can get that by changing to 50% of the width. Stop the app and try this:

 
button.layer.cornerRadius = button.frame.height * 0.50

Run again and you get circular-end buttons.

If you apply this to a button that has the same width and height, like the square button, you’ll get a round button. Stop the app and try this:

squareButton.layer.cornerRadius = squareButton.frame.height * 0.50

Run again and you get a circle for a button.

There’s one more trick I want to show you. Stop the app, go to the storyboard and change the backgroundImage to Pizza Marg.

Run again and you get a square button

. cornerRadius Only applies to background colors and borders by default. For the background to be masked you need one more line

squareButton.layer.masksToBounds = true

Which sets everything to be masked. Now if you run, you get the circle button.

There’s one thing I want to point our about masksToBounds. It will kill any drop shows you use. Add the method buttonShadow I made
Run again. You see the stackview buttons have shadows but the round button does not. The mask of masksToBounds cuts off the shadow. In order to use both, you’ll need a better understanding of masks I’ll get to in a later tip.
Instead of messing with lots of assets, if you need rounded buttons you may want to explore CALayer’s corner radius as an option.

The Whole Code

You can also find a download of this code on GitHub

//
//  ViewController.swift
//  RoundButtons
//
//  A exercise file for iOS Development Tips Weekly
//  by Steven Lipton (C)2018, All rights reserved
//  For videos go to http://bit.ly/roundButtonsLinkedIn
//  For code go to http://bit.ly/AppPieGithub
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var stackView: UIStackView!
    @IBOutlet weak var squareButton: UIButton!
    @IBOutlet weak var imageView: UIImageView!
    
    
    override func viewDidLayoutSubviews() { //<-- Add code here
        squareButton.layer.cornerRadius = squareButton.frame.height * 0.50
        squareButton.layer.masksToBounds = true
        for view in stackView.arrangedSubviews{
            if let button = view as? UIButton{
                button.layer.cornerRadius = button.frame.height * 0.50
            }
        }
    }
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        imageShadow()
    }
    
    func imageShadow(){
        imageView.layer.shadowColor = UIColor(named: "#0000FF Match 1")?.cgColor
        imageView.layer.shadowOffset = CGSize(width: 5, height: 6)
        imageView.layer.shadowRadius = 4.0
        imageView.layer.shadowOpacity = 0.4
    }
    
    func buttonShadow(button:UIButton){
        button.layer.shadowColor = UIColor(named: "#0000FF Match 1")?.cgColor
        button.layer.shadowOffset = CGSize(width: 5, height: 5)
        button.layer.shadowRadius = 4.0
        button.layer.shadowOpacity = 0.4
    }

}

4 responses to “Make Round Buttons and UIViews”

  1. WHAT is clipbounds and Maskbounds use in code in swift 4 ios

  2. The whole square area of UIButton is clickable though it is rounded. Means Outside of Rounded button It is clickable. How to handle this issue?

    1. Everything is built on CGrects, so you’re usually stuck with a rectangle. You’d have to control the touch region in some way that I can’t think of how to do in UIKit.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: