Получить UIAlertController из UIAlertAction?

Я хочу вызвать функцию, а не использовать замыкание с UIAlertAction. Можно ли получить ссылку на UIAlertController, которому принадлежит 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?
}

person Mitchell Hudson    schedule 05.10.2015    source источник


Ответы (3)


Действие не имеет ссылки на содержащееся в нем предупреждение. Тем не менее, это всего лишь вопрос планирования наперед. Если вам нужно, чтобы okAlert имел ссылку на контроллер предупреждений, дайте эту ссылку:

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

Вам все равно понадобится замыкание, чтобы захватить alert и передать его:

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)
}))

Могут быть детали, которые нужно проработать. Но дело в том, что если вы хотите, чтобы okAlert жил где-то еще, вы можете это сделать.

person matt    schedule 06.10.2015

Можете ли вы попробовать код ниже:

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

с callback:

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

Я не знаю точно, чего ты хочешь. Но я думаю, вы хотите получить TextField внутри UIAlertController. Может быть, приведенный ниже код поможет вам.

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)
    }
}

Надеюсь, это поможет!

person Long Pham    schedule 05.10.2015
comment
Спасибо за ответ. Думаю, моя цель была неясна. Мне нужно добраться до текстового поля в AlertController. Я хотел бы получить это из функции callBack. Я понимаю, что я мог бы использовать закрытие. Мне было интересно, как справиться с этим без закрытия. - person Mitchell Hudson; 06.10.2015

В итоге я создал новый подкласс UIAlertAction:

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

затем я создаю действия как:

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

и в коде, который добавляет действие к предупреждению, у меня есть:

alertController.addAction(myAction)
myAction.alertController = alertController
person GilroyKilroy    schedule 27.10.2017