How to create and use Custom Dialog boxes in iOS?

Shubham Singh
Mac O’Clock
Published in
5 min readApr 1, 2020

Create a custom dialog box that can be used instead of the UIAlertController.

Now I know that Apple provides the UIAlertController to show a dialog box with actions and everything, but it’s not customizable except the messages and the actions. By creating a Custom View and displaying it as a kind of pop up box gives you much more freedom and allows you to be creative with it.

Here’s what the final application will look like after we are done.

This tutorial assumes you have the knowledge of:

  • Swift 4
  • Xcode
  • Auto Layout
  • View Transitions

Let’s get started with it

1. Create the required files for the project

1. The project structure

For the project, I have created a group for the Custom views which will contain the UI’s which we will display as a pop-up. These views have their Storyboard to keep things clean. Aside from that, we have a Home view controller and the Main storyboard.

2. Prepare the UI in the storyboard

The next thing we need to do is to create the UI with the help of storyboards and auto layout.

Create the UI for HomeViewController

2. Home View Controller in Main.storyboard

The Home view’s UI is pretty straightforward and here we are using two UIButton’s whose outlets are connected to the controller.

Create the UI for the Dialog Box 1

3. Normal Popup view controller in CustomView.storyboard

The first dialog box’s UI contains a view that contains 2 UILabels, 1 UIImageView and a UIButton whose outlet is connected to the controller.

Create the UI for Dialog Box 2

4. Popup with Actions view controller in CustomView.storyboard

The second dialog box’s UI is almost the same as above, the only difference being that it has 2 UIButton’s whose outlets are connected to the view controller.

3. Writing the code for the View Controllers

By now we have created the UI’s and we have connected the outlets to their specific view controllers. Now the only thing remaining is to write some code in the controllers.

Code for the Home View Controller

import UIKitclass HomeViewController: UIViewController, PopUpDelegate {let url: String = “https://www.apple.com/in/ios/app-store/"//MARK:- lifeCycle methods for the view controlleroverride func viewDidLoad() {
super.viewDidLoad()
}
//MARK:- outlets for the view controller@IBAction func customPopupPressed(_ sender: Any) {
NormalPopupViewController.showPopup(parentVC: self)
}
@IBAction func customPopupActionPressed(_ sender: Any) {
PopUpActionViewController.showPopup(parentVC: self)
}
//MARK:- functions for the view controllerfunc handleAction(action: Bool) {
//opening a link to the app store if the user clickes on the go to app store button
if (action) {
guard let url = URL(string: url) else {
return
}
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}

So in here, we are adopting the PopUpProtocol defined in the Dialog Box 2 so that we can handle user action on the dialog box, based on user actions we are opening the AppStore link in Safari.

Code for the Dialog Box 1 Controller

import UIKitclass NormalPopupViewController: UIViewController {static let identifier = “NormalPopupViewController”//MARK:- outlets for the viewController@IBOutlet weak var dialogBoxView: UIView!
@IBOutlet weak var okayButton: UIButton!
//MARK:- lifeCycle methods for the view controlleroverride func viewDidLoad(){
super.viewDidLoad()
//adding an overlay to the view to give focus to the dialog box
view.backgroundColor = UIColor.black.withAlphaComponent(0.50)
//customizing the dialog box view
dialogBoxView.layer.cornerRadius = 6.0
dialogBoxView.layer.borderWidth = 1.2
dialogBoxView.layer.borderColor = UIColor(named: “dialogBoxGray”)?.cgColor
//customizing the okay button
okayButton.backgroundColor = UIColor(named: “primaryBackground”)?.withAlphaComponent(0.85)
okayButton.setTitleColor(UIColor.white, for: .normal)
okayButton.layer.cornerRadius = 4.0
okayButton.layer.borderWidth = 1.2
okayButton.layer.borderColor = UIColor(named: “primaryBackground”)?.cgColor
}
//MARK:- outlet functions for the viewController@IBAction func okayButtonPressed(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
//MARK:- functions for the viewControllerstatic func showPopup(parentVC: UIViewController){ //creating a reference for the dialogView controller
if let popupViewController = UIStoryboard(name: “CustomView”, bundle: nil).instantiateViewController(withIdentifier: “NormalPopupViewController”) as? NormalPopupViewController {
popupViewController.modalPresentationStyle = .custom
popupViewController.modalTransitionStyle = .crossDissolve
//presenting the pop up viewController from the parent viewController parentVC.present(popupViewController, animated: true)
}
}
}

The code for Dialog Box 1 contains a viewDidLoad method in which we have customized the views by adding round corners and borders to them. We also have one static function which can be called by the parent which displays this view in the calling parent View controller.

Code for the Dialog Box 2 Controller

import UIKit//Protocol to inform the Parent viewController to take some action based on the dialog boxprotocol PopUpDelegate {
func handleAction(action: Bool)
}
class PopUpActionViewController: UIViewController {static let identifier = “PopUpActionViewController”var delegate: PopUpDelegate?//MARK:- outlets for the view controller@IBOutlet weak var dialogBoxView: UIView!
@IBOutlet weak var gotoStoreButton: UIButton!
@IBOutlet weak var laterButton: UIButton!
//MARK:- lifecyle methods for the view controlleroverride func viewDidLoad() {
super.viewDidLoad()
//adding an overlay to the view to give focus to the dialog box
view.backgroundColor = UIColor.black.withAlphaComponent(0.50)
//customizing the dialog box view
dialogBoxView.layer.cornerRadius = 6.0
dialogBoxView.layer.borderWidth = 1.2
dialogBoxView.layer.borderColor = UIColor(named: “dialogBoxGray”)?.cgColor
//customizing the go to app store button
gotoStoreButton.backgroundColor = UIColor(named: “primaryBackground”)?.withAlphaComponent(0.85)
gotoStoreButton.setTitleColor(UIColor.white, for: .normal)
gotoStoreButton.layer.borderWidth = 1.2
gotoStoreButton.layer.cornerRadius = 4.0
gotoStoreButton.layer.borderColor = UIColor(named: “primaryBackground”)?.cgColor
}
//MARK:- outlet functions for the viewController@IBAction func goToStorePressed(_ sender: Any) {
self.delegate?.handleAction(action: true)
self.dismiss(animated: true, completion: nil)
}
@IBAction func laterButtonPressed(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
//MARK:- functions for the viewControllerstatic func showPopup(parentVC: UIViewController){ //creating a reference for the dialogView controller
if let popupViewController = UIStoryboard(name: “CustomView”, bundle: nil).instantiateViewController(withIdentifier: “PopUpActionViewController”) as? PopUpActionViewController {
popupViewController.modalPresentationStyle = .custom
popupViewController.modalTransitionStyle = .crossDissolve
//setting the delegate of the dialog box to the parent viewController
popupViewController.delegate = parentVC as? PopUpDelegate
//presenting the pop up viewController from the parent viewController parentVC.present(popupViewController, animated: true)
}
}
}

The code for Dialog Box 2 is almost the same as Dialog box 1 and the only difference in this being that we have defined a protocol here and assigning the delegate to the parent view controller.

and we are done, Congratulations 🎉

If you want the code it’s hosted in my gitHub Repository which can be found here.

Thanks for reading!

--

--

Shubham Singh
Mac O’Clock

iOS developer at Dailyrounds. I’m Immensely passionate about iOS & I’m also an avid UI/UX enthusiast. Connect with me on my Instagram/Twitter — @shubham_iosdev