Get the UIAlertController from UIAlertAction?
Asked Answered
A

3

6

I want to call a function rather than use a closure with a UIAlertAction. Is it possible to get a reference to the UIAlertController that owns the UIAlertAction?

alert = UIAlertController(title: "City", message: "Enter a city name", preferredStyle: UIAlertControllerStyle.Alert)
UIAlertActionStyle.Default, handler: okAlert)

//...

func okAlert(action: UIAlertAction) {
    // Get to alert here from action?
}
Aerodyne answered 5/10, 2015 at 2:10 Comment(0)
L
6

An action has no reference to its containing alert. Still, it's just a matter of planning ahead. If you need okAlert to have a reference to the alert controller, then give it that reference:

func okAlert(_ action: UIAlertAction, _ alert:UIAlertController) {
    // Get to alert here?
    // yes! it is `alert`!
}

You will still need a closure to capture alert and pass it:

let alert = UIAlertController(
    title: "City", message: "Enter a city name", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title:"OK", style:.Default, handler: {
    action in self.okAlert(action, alert)
}))

There may be details to work out. But the point is, if you want okAlert to live somewhere else, you can do it.

Linder answered 6/10, 2015 at 5:17 Comment(0)
E
0

Can you try below code:

let alert = UIAlertController(title: "Test alert title", message: "Test alert body", preferredStyle: .Alert)
alert.addAction(callback())
presentViewController(alert, animated: true, completion: nil)

with callback:

func callback() -> UIAlertAction {
     return UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in
         print("alert action")
    })
 }

I don't know exactly what you want. But i think you want to get a TextField inside UIAlertController. May be that below code will help you.

var alert: UIAlertController?
let tfTag = 123
override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    if alert == nil {
        self.alert = UIAlertController(title: "Test alert title", message: "Test alert body", preferredStyle: .Alert)

        let action = UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in
            // Get your TextField
            if let tf = self.alert!.view.viewWithTag(self.tfTag) as? UITextField {
                print("Value: \(tf.text)")
            }

        })

        self.alert!.addAction(action)

        // Insert UITextField
        let textField = UITextField()
        textField.text = "Hello World"
        textField.tag = tfTag
        self.alert!.view.addSubview(textField)
        presentViewController(self.alert!, animated: true, completion: nil)
    }
}

Hope that helps!

Execution answered 5/10, 2015 at 2:49 Comment(1)
Thanks for the reply. I guess my purpose wasn't clear. I need to get to a textField in the AlertController. I'd like to get this from the callBack function. I understand that I could use a closure. I was wondering about handling this without a closure.Aerodyne
W
0

What I wound up doing was create a new subclass of UIAlertAction:

public class UIAlertActionWithAlertController : UIAlertAction {
    public weak var alertController: UIAlertController?
}

then I create actions as:

let myAction = UIAlertActionWithAlertController(title: "Action", style: .default) { (action) in
   if let alertController = (action as! UIAlertActionWithAlertController).alertController {
        // Use alertController here
   }}

and in the code that adds the action to the alert I have:

alertController.addAction(myAction)
myAction.alertController = alertController
Willow answered 27/10, 2017 at 19:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.