Agung
Agung

Reputation: 13863

how to create an alert in a swift file model that works for various view controller

I am a beginner in iOS development. I am trying to make a Swift file which only contains a method to show an alert. This model will be used in some view controller.

I make a Swift file and the code to make an alert is like this:

import UIKit

class Alert : UIAlertController {
    func showAlert (alertTitle: String, alertMessage: String, actionTitle: String) {
        let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert)
        let alertAction1 = UIAlertAction(title: actionTitle, style: .default) { (action) in

        }

        alert.addAction(alertAction1)
        present(alert, animated: true, completion: nil)
    }
}

and then I implement this class in a view controller

import UIKit

class ViewController: UIViewController {
    var x = 10
    var alert = Alert()

    override func viewDidLoad() {
        super.viewDidLoad()

        if x < 15 {
            test()
        }
    }

    func test() {
       alert.showAlert(alertTitle: "Opps", alertMessage: "less than 15", actionTitle: "OK")
    }
}

But I get an error:

Warning: Attempt to present <UIAlertController: 0x7fcc0bc05fc0> on <testAlert.Alert: 0x7fcc0bc04bc0> whose view is not in the window hierarchy!

What should I do?

Upvotes: 0

Views: 662

Answers (2)

rmaddy
rmaddy

Reputation: 318934

There's no reason that your Alert class should be extending UIViewController since your Alert class isn't a view controller.

What you should be doing is making your showAlert method a method of UIViewController via an extension.

Change:

class Alert : UIAlertController {

to:

extension UIAlertController {

Then when you want to show an alert from a view controller (such as your ViewController class, you simply call showAlert.

class ViewController: UIViewController {
    func test() {
       showAlert(alertTitle: "Opps", alertMessage: "less than 15", actionTitle: "OK")
    }
}

Upvotes: 1

Valerii Lider
Valerii Lider

Reputation: 1814

The error tells everything: you are creating instance of Alert, which is UIAlertController, which is creating another UIAlertController that you want to present on that instance of Alert, which is not even presented by your view controller.

Why don't you simply create an extension for UIViewController with that method?

Try following:

extension UIViewController {
    func showAlert(title: String, message: String, …) {
        …
        present(alert, animated: true, completion: nil)
    }
}

You can call this method from any UIViewController, and it will create UIAlertController that will present from your UIViewController:

// from your UIViewController code, for example from viewDidAppear method
self.showAlert(title: "Wow!", message: "It works!", actionTitle: "Dismiss")

Upvotes: 1

Related Questions