有没有办法将闭包传递给UIAlertAction,它将在Swift中返回一个String?

问题描述 投票:0回答:1

我正在尝试更多地了解Swift Closure概念,我有这个问题,我有以下UIAlertController方法:

 public static func showSerialNumberAlertController(handler: @escaping (UIAlertAction) -> String?) {
    let alertController = UIAlertController(title: "Serial Number", message: "Please enter your serial number", preferredStyle: .alert)

    // ADD ACTIONS HANDLER
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
    cancelAction.isEnabled = true
    alertController.addAction(cancelAction)

    let continueAction = UIAlertAction(title: "Continue", style: .default) { (_) in
        let serialNumberField = alertController.textFields![0] as UITextField
        let text = serialNumberField.text
        print("Serial number entered: \(text!)")
    }
    continueAction.isEnabled = false
    alertController.addAction(continueAction)

    // ADD TEXT FIELDS
    alertController.addTextField { (textField) in
        textField.placeholder = "Serial number"
        // enable continue button when serial not empty
        NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextFieldTextDidChange, object: textField, queue: OperationQueue.main) { (notification) in
            continueAction.isEnabled = textField.text != "" && textField.text?.count as! Int > 3
        }
    }

    alertController.view.tintColor = Colors.mainColor
    getRootViewController()?.present(alertController, animated: true)
}

现在我要做的是用我从外部收到的处理程序替换continueAction UIAlertAction的处理程序,当用户按下继续按钮并将其作为返回值传递时,将从序列号UITextField中提取文本。

所以我在这个范围之外的另一个文件中有这个方法,我从中调用这个静态方法:

public func getSerialFromAlert(alertController: UIAlertController) -> String? 
{
    let serialNumberField = alertController.textFields![0] as UITextField
    let text = serialNumberField.text
    print("Serial number entered: \(text!)")
    return text
}

我想将此方法作为处理程序传递但是当我这样做时,我收到此错误:

无法转换类型'(UIAlertAction) - > String?'的值期望参数类型'((UIAlertAction) - > Void)?'

所以问题是:是否有可能实现这一点并传递一个将值作为参数返回的处理程序?如果是这样,那么这样做的正确方法是什么?如果没有,那么为了提取数据而必须访问警报视图的UIAlertController操作委托的替代方案是什么?

ios swift closures handler uialertaction
1个回答
2
投票

如果我理解正确,您可以将方法签名更改为

showSerialNumberAlertController(completion: @escaping (String) -> Void)

在此函数中将continue动作更改为:

let continueAction = UIAlertAction(title: "Continue", style: .default) { (_) in
    let serialNumberField = alertController.textFields![0] as UITextField
    let text = serialNumberField.text
    completion(text ?? "")
}

最后你调用这样的方法:

UIAlertController.showSerialNumberAlertController { serial in
    print("Serial number entered: \(serial)")
}
© www.soinside.com 2019 - 2024. All rights reserved.