UIButton Subclass And Initialization For Storyboard or Code

Let’s look at how to design a subclass of UIButton with Swift, with initializers such that it can be used in a storyboard, or programmatically in code.

We’ll discuss initialization requirements, and illustrate both cases with a complete demo app that has buttons with left aligned text and a right aligned image.

The image I’ll use is one I created with the awesome Sketch App, and used previously as a custom edit icon in table view rows.

We start with a usual Single View Application template, and a project called UIButtonAlignedImage. Let’s create a group called images, and add the edit icon images to the project in the images group. Next we create an EditIcon image set, with Render As set to Template Image.

Let’s define the class now that can be used from a storyboard or code.

I’ve commented the code, but some short discussion anyway.

We override the designated initializer from UIView because when subclassing, convenience initializers must delegate across, not up. What that means is we can’t just call super.init from our new convenience initializer. Instead, we override init and then call across to our own init via self.init. That designated initializer then makes the call up to super.init.

You can see these rules in the Swift Programming Language section on Initialization, and specifically the subsection titled Initializer Delegation for Class Types. Below is a screenshot with a summary of some of these rules, and the entire section is definitely recommended reading.

As I mentioned in the comments, credit to Peter Kreinz for his solution on Stack Overflow for a method that can return a UIImage with an alpha value.

The next part is some storyboard definition for the View Controller Scene, consisting of a UIStackView, containing a UILabel and UIButton.

The label is configured with a lower vertical hugging priority than the button, so it takes up all the extra space. The EditIcon image set is specified as the Image for the button. You’ll see that I set the Type to System. Not visible in the screenshot is that I’ve set the button Background to Light Text Color, so it is offset a little from the view background and looks like some buttons you see in apps such as Uber and Amazon.

I’ve noted in the code comments that if it was Custom, some additional configuration would be needed in code.

Let’s run the app now and see the result with only the button that is defined in the storyboard.

Next we’ll add a button in code so that it looks just like the one we added via the storyboard. We need to add an IBOutlet for the UIStackView, into the ViewController, so that we’ll be able to add the button into the stack view.

With the IBOutlet in place, and code to add the button, here is the ViewController.

The frame can start out as zero because it will be sized according to the UIStackView. Since the button is Custom by default when defined in code, we set it’s title color for normal and highlighted, and also set the font to 15.0 so it matches the other button. Finally, the same backgroundColor is specified for this button so it matches the storyboard one.

Here is the app running again with this new button instantiated from code in the viewDidLoad method.

You can see that we have two buttons that look the same, and if you run the app and click them, they behave the same when highlighted as well.

You can download the project for this tutorial here on GitHub.

If you have comments or suggestions, those are always appreciated.

Leave a Comment: