You are currently viewing How to Use ASAuthorizationAppleIDButton in Storyboard

How to Use ASAuthorizationAppleIDButton in Storyboard

At WWDC 2019, Apple introduced Sign in with Apple. It provides a simple and secure way for people to sign in to apps using the Apple IDs they already have. In order to support Sign in with Apple, developers must use the sign in button provided by Apple — ASAuthorizationAppleIDButton.

Unfortunately, the ASAuthorizationAppleIDButton class does not have storyboard support. Therefore, developers will have to add the sign in button programmatically, causing them not able to enjoy the benefits of using storyboards.

The benefits of using storyboards include:

  • Can easily setup auto layout constraints.
  • Better visualisation on the overall screen design.
  • Much easier to handle various size classes.
  • Less code written means less bugs.

In this article, I will show you how you can use ASAuthorizationAppleIDButton in storyboard by using a custom UIButton.

Generally, here’s what you need to do.

  1. Create a custom UIButton.
  2. Add ASAuthorizationAppleIDButton as subview.
  3. Create IBInspectable for button corner radius.
  4. Create IBInspectable for button type and style.
  5. Handle button tap event.

With all that being said, let’s go through the steps in detail one by one.


#1. Create a Custom UIButton

To create a custom UIButton, press ⌘N → select Cocoa Touch Class. We will name the custom button MyAuthorizationAppleIDButton and make it subclass of UIButton.

Create UIButton subclass in Xcode
Create UIButton subclass

Next, implement all the required init methods so that the custom button can be used in storyboard.

class MyAuthorizationAppleIDButton: UIButton {

    override public init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

#2. Add ASAuthorizationAppleIDButton as Subview

Before we proceed with the implementation, let’s configure our Xcode in a way that can ease us in the custom button development.

Getting Ready

First, let’s open your storyboard and MyAuthorizationAppleIDButton.swift side by side using the assistant canvas. To do this, press ⌘⇧O (command + shift + O), type your storyboard name and then press ⌥↩︎ (option + enter) to open it at the assistant canvas.

You can learn more about Xcode navigation shortcuts in this article.

Source editor and storyboard side by side in Xcode
Source editor and storyboard side by side

Next, in your storyboard, add a UIButton to the view controller and set its class to MyAuthorizationAppleIDButton.

In addition, add the following auto layout constraints to the button.

  • Horizontally in container
  • Vertically in container
  • Width: 250pt
  • Height: 46pt
Auto layout configuration for custom button using Xcode
Auto layout configuration for custom button

Lastly, go to the Editor menu, and then enable Automatically Refresh Views. By enabling this, you will be able to see the button’s appearance being rendered simultaneously whenever there are changes in MyAuthorizationAppleIDButton class. You should see this in action in a short while.

Enable Automatically Refresh Views in Xcode
Enable Automatically Refresh Views

Adding ASAuthorizationAppleIDButton

Now, let’s head back to MyAuthorizationAppleIDButton.swift and continue the custom button implementation.

In order to use ASAuthorizationAppleIDButton, we must first import the AuthenticationServices framework.

import AuthenticationServices

We also need to define a private ASAuthorizationAppleIDButton instance named authorizationButton.

private var authorizationButton: ASAuthorizationAppleIDButton!

Do note that authorizationButton is of implicitly unwrapped optional type because we are confident that it won’t be nil for the entire lifecycle of the custom button.

To learn more about implicitly unwrapped optional, check out this article.

Next, we will need to make our custom button look exactly the same as the ASAuthorizationAppleIDButton. The idea is to add the ASAuthorizationAppleIDButton as subview and force it to follow the size of our custom button.

We can achieve that by overriding the draw(_:) method of our custom button.

override public func draw(_ rect: CGRect) {
    super.draw(rect)

    // Create ASAuthorizationAppleIDButton
    authorizationButton = ASAuthorizationAppleIDButton(authorizationButtonType: .default, authorizationButtonStyle: .black)

    // Show authorizationButton
    addSubview(authorizationButton)

    // Use auto layout to make authorizationButton follow the MyAuthorizationAppleIDButton's dimension
    authorizationButton.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        authorizationButton.topAnchor.constraint(equalTo: self.topAnchor, constant: 0.0),
        authorizationButton.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0.0),
        authorizationButton.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0.0),
        authorizationButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0.0),
    ])
}

Up until this point, you will find that the button you added to storyboard just now is still a boring white colour system button.

To trigger the rendering in storyboard, add the @IBDesignable keyword before the start of the MyAuthorizationAppleIDButton class’s definition and see the system button magically transform into the Sign in with Apple button.

@IBDesignable
class MyAuthorizationAppleIDButton: UIButton {

    // ...
    // ...
    // ...

}
Show Sign in with Apple button in storyboard in Xcode
Show Sign in with Apple button in storyboard

After successfully showing the Sign in with Apple button in storyboard, we can now work on customising the button’s appearance.

By looking into the Apple official documentation, you will find that there are 3 styling properties in ASAuthorizationAppleIDButton that we can utilise to change the appearance of the button.

ASAuthorizationAppleIDButton styling properties
ASAuthorizationAppleIDButton styling properties

In the next section, we will look into how to add these 3 properties into our custom button. On top of that, we will also make all these 3 properties available for customisation in storyboard attributes inspector by using @IBInspectable.


#3. Create IBInspectable for Button Corner Radius

The way to make corner radius available in the storyboard attributes inspector is quite straightforward. We just need to define a cornerRadius variable for MyAuthorizationAppleIDButton and tag it with @IBInspectable.

@IBInspectable
var cornerRadius: CGFloat = 6.0

Note that we are using 6.0 as the default value of cornerRadius as that is the default corner radius of ASAuthorizationAppleIDButton.

Next, go to the draw(_:) method and set cornerRadius as authorizationButton‘s corner radius.

authorizationButton.cornerRadius = cornerRadius

Here’s the updated MyAuthorizationAppleIDButton.swift.

Set custom button corner radius
Set authorizationButton corner radius

We can now head over to storyboard and try changing the corner radius value in the attributes inspector.

You should be able to see the custom button’s appearance in storyboard being updated when you update the corner radius value in the attributes inspector.

Changing ASAuthorizationAppleIDButton 
 corner radius in attributes inspector
Changing corner radius in attributes inspector

#4. Create IBInspectable for Button Type and Style

IBInspectable only supports basic data types such as String, Int and CGFloat. In other words, data types such as ASAuthorizationAppleIDButton.ButtonType and ASAuthorizationAppleIDButton.Style are not supported by IBInspectable. Therefore, we must find a way to keep track of the button type and style by using basic data type.

Fortunately, by looking into the definition of both ASAuthorizationAppleIDButton.ButtonType and ASAuthorizationAppleIDButton.Style, you will notice that both of them have raw value of type Int.

ButtonType and Style raw value data type
ButtonType and Style raw value data type

As a result, we can define variables of type Int and use @IBInspectable to make them available in the storyboard attributes inspector.

@IBInspectable
var authButtonType: Int = ASAuthorizationAppleIDButton.ButtonType.default.rawValue
    
@IBInspectable
var authButtonStyle: Int = ASAuthorizationAppleIDButton.Style.black.rawValue

As you can see, for code above, authButtonType will take the ASAuthorizationAppleIDButton.ButtonType.default‘s raw value as its default value. Meanwhile, authButtonStyle will take ASAuthorizationAppleIDButton.Style.black‘s raw value as its default value.

Next, we will update the draw(_:) method to initialise the ASAuthorizationAppleIDButton instance using authButtonType and authButtonStyle.

let type = ASAuthorizationAppleIDButton.ButtonType.init(rawValue: authButtonType) ?? .default
let style = ASAuthorizationAppleIDButton.Style.init(rawValue: authButtonStyle) ?? .black
authorizationButton = ASAuthorizationAppleIDButton(authorizationButtonType: type,
                                                   authorizationButtonStyle: style)

Notice that we need to handle the initialisation failure for both type and style by falling back to their default value, this is because we have no control over the value being inputted from the storyboard attributes inspector.

With all that being done, we can head back to storyboard and see everything in action!

Changing ASAuthorizationAppleIDButton 
type and style in attributes inspector
Changing button type and style in attributes inspector

Pretty cool isn’t it! 😎

At this point, if you create an IBAction and connect it to our custom button touch up inside event, you will notice that the action is not being triggered. This is because the touch up inside event has been hijacked by the ASAuthorizationAppleIDButton subview.

In the following section, we will look into how we can solve this issue.


#5. Handle Button Tap Event

The solution to the button tap event issue is pretty simple, the idea is to handle the authorizationButton‘s touch up inside event and forward it to our custom button.

Let’s go ahead and set the selector for the authorizationButton‘s touch up inside event.

// Set selector for touch up inside event so that can forward the event to MyAuthorizationAppleIDButton
authorizationButton.addTarget(self, action: #selector(authorizationAppleIDButtonTapped(_:)), for: .touchUpInside)

Here’s the implementation of the authorizationAppleIDButtonTapped(_:) method.

@objc func authorizationAppleIDButtonTapped(_ sender: Any) {
    // Forward the touch up inside event to MyAuthorizationAppleIDButton
    sendActions(for: .touchUpInside)
}

Note that the sendActions(for:) method will trigger the touch up inside event of our custom button.

Here’s the updated MyAuthorizationAppleIDButton.swift.

Forwarding touch up inside event in Swift
Forwarding touch up inside event

With that, the MyAuthorizationAppleIDButton should be able to trigger its touch up inside event without any problem.


Something to Take Note

While testing the sample code, I noticed that there are auto layout constraint warnings being shown at the debug area when the custom button has width larger than 375pt or height larger than 64pt.

Auto layout warnings of ASAuthorizationAppleIDButton
Auto layout warnings when width > 375 and height > 64

It seems like Apple has added auto layout constraints to limit the dimension of the ASAuthorizationAppleIDButton. I would recommend all developers to go through the Human Interface Guidelines, and only use the suggested button dimension in order to avoid apps being rejected by Apple.


Wrapping Up

The custom button that we have created is fully functioning and highly customisable. You can definitely reuse it in your other iOS projects. Feel free to get the full sample code here.

To reuse it, just add MyAuthorizationAppleIDButton.swift to your iOS project, after that add a custom button of type MyAuthorizationAppleIDButton to your storyboard, then you are good to go.

Last but not least, if you do not want Xcode to rebuild your projects every time you make changes on your code, feel free to disable Automatically Refresh Views under the Editor menu.


Further Readings


If you find this article helpful, feel free to share it. If you have any comments or questions, please leave it in the comment section below.

Follow me on Twitter for more articles related to iOS development.

Thanks for reading! 👨🏼‍💻


👋🏻 Hey!

While you’re still here, why not check out some of my favorite Mac tools on Setapp? They will definitely help improve your day-to-day productivity. Additionally, doing so will also help support my work.

  • Bartender: Superpower your menu bar and take full control over your menu bar items.
  • CleanShot X: The best screen capture app I’ve ever used.
  • PixelSnap: Measure on-screen elements with ease and precision.
  • iStat Menus: Track CPU, GPU, sensors, and more, all in one convenient tool.