This tutorial is concise and assumes that you already know how to add constraints, connect outlets, and create delegates.

Leave a comment below if you are a beginner and need assistance with these!


First let us design the alert view.

Drag a ViewController on to your storyboard.

Add a view, add necessary constraints, header labels and the most important part – a UIPickerView. Also add OK and Cancel buttons at the bottom. Here’s how my view looks after design.


Now create a Swift class for this ViewController that we created, named MyTimePickerAlert.swift. We also need to create a Delegate for this, so that we can communicate data back to our main view controller from where we will be presenting this alert.

So here’s the initial code for the file MyTimePickerAlert.swift.

import UIKit

protocol MyTimePickerAlertDelegate: class {
    func pickerAlertSelected(t1: String, t2: String)
    func pickerAlertCancel()

class MyTimePickerAlert: UIViewController {


Now, inside the class MyTimePickerAlert, declare outlets for our significant views.

    @IBOutlet weak var alertView: UIView!
    @IBOutlet weak var cancelButton: UIButton!
    @IBOutlet weak var okButton: UIButton!
    @IBOutlet weak var pickerView: UIPickerView!

also declare a variable for the delegate

    var delegate: MyTimePickerAlertDelegate?

Also, declare arrays to store the start and end times, and a dateformatter instance that will be used for formatting the times.

    var startTimes = [String]()
    var endTimes = [String]()
    let timeFormatter = DateFormatter()    

Let us write a function to get a list of all the time values. We shall also pass a parameter to determine the offset for the end times; because we do not want the user to be able to select an END time that is earlier than the START time.

extension MyTimePickerAlert {
    func getTimeList(from: Int) -> [String] {
        let alllist: [String] = [
            "1:00 AM","2:00 AM","3:00 AM","4:00 AM","5:00 AM", "6:00 AM", "7:00 AM", "8:00 AM", "9:00 AM","10:00 AM","11:00 AM", "12:00 PM", "1:00 PM", "2:00 PM", "3:00 PM", "4:00 PM", "5:00 PM", "6:00 PM", "7:00 PM", "8:00 PM", "9:00 PM", "10:00 PM", "11:00 PM", "12:00 AM"]
        var list: [String] = []
        for i in from...alllist.count-1 {
        return list   

Now write the delegate and datasource methods for populating the data of the PickerView.

extension MyTimePickerAlert: UIPickerViewDelegate, UIPickerViewDataSource {

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 2
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        switch component {
        case 0:
            return startTimes.count
        case 1:
            return endTimes.count
            return 0
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        var label: UILabel
        if let view = view as? UILabel {
            label = view
        } else {
            label = UILabel()
        label.textColor = .black
        label.textAlignment = .center
        label.font = UIFont.systemFont(ofSize: 15)
        var text = ""
        switch component {
        case 0:
            text = startTimes[row]
        case 1:
            text = endTimes[row]
        label.text = text
        return label
    //this is for reloading the END times list, according to the value selected as the START time.
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if (component == 0) {
            endTimes = getTimeList(from: row)

And, let us initialise the views and set the button actions; and call the delegate function upon user selecting OK.

    override func viewDidLoad() {
        pickerView.delegate = self
        pickerView.dataSource = self
        timeFormatter.timeStyle = .short
        startTimes = getTimeList(from: 0)
        endTimes = getTimeList(from: 0)
        cancelButton.addTarget(self, action: #selector(cancelMe), for: .touchUpInside)
        okButton.addTarget(self, action: #selector(okMe), for: .touchUpInside)
    @objc func okMe() {
        delegate?.pickerAlertSelected(t1: startTimes[pickerView.selectedRow(inComponent: 0)], t2: endTimes[pickerView.selectedRow(inComponent: 1)])
        self.dismiss(animated: true, completion: nil)
    @objc func cancelMe() {
        self.dismiss(animated: true, completion: nil)

Go back to your storyboard, find the view controller that we designed for the alert, and change its class to MyTimePickerAlert, and also set storyboard ID as mytimepicker (or anything you like).

Also do not forget to connect all the IBOutlets to their respective views.

Finally, go to the main ViewController class – the screen from where you wish to launch the Picker Alert view and add this code to present the alert view and to handle the actions of OK or Cancel buttons.

extension ViewController: MyTimePickerAlertDelegate {

    @objc func showTimePicker() {
        let customAlert = self.storyboard?.instantiateViewController(withIdentifier: "mytimepicker") as! MyTimePickerAlert
        customAlert.providesPresentationContextTransitionStyle = true
        customAlert.definesPresentationContext = true
        customAlert.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
        customAlert.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
        customAlert.delegate = self
        self.present(customAlert, animated: true, completion: nil)

    func pickerAlertCancel() {


    func pickerAlertSelected(t1: String, t2: String) {
        //Do something with the selected times, display it somewhere
        print("START time is \(t1) and END time is \(t2)")

Now just call the function showTimePicker() from any button or textfield click.