无法从Alert返回字符串

时间:2016-03-26 23:10:48

标签: ios swift

我正在构建一个待办事项列表应用程序,我在从警报返回文本输入时遇到了很多麻烦。

这是一个单独的文件:'AddItem.swift'

func showAddItemDialog(view: UIViewController) -> String {
    var textOfTask = UITextField()
    var textValue = ""

    let diag = UIAlertController(title: "Add Task", message: "Enter a task name", preferredStyle: .Alert)
    diag.addTextFieldWithConfigurationHandler({ (textField) -> Void in })
    diag.addAction(UIAlertAction(title: "Add", style: .Default, handler: { (action) -> Void in
        textOfTask = diag.textFields![0] as UITextField
        textValue = textOfTask.text!

        addListItem(textValue)
    }))

    diag.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in }))
    view.presentViewController(diag, animated: true, completion: nil)

    print("returning " + textValue)
    return textValue
}

我正在尝试将Alert的文本框的文本值('textValue')返回给调用者。

我尝试了很多方法,但没有提出任何方法,我上面的内容没有返回任何内容,因为函数没有停止并在返回之前等待警报显示。我想避免将此代码放入ViewController文件中,因为我已经读到这是不好的做法,但我真的无法理解这一点。

如果有人有任何想法,请告诉我!谢谢!

编辑:

我用以下方法调用此函数:

@IBAction func didPressAdd(sender: AnyObject) {
    showAddItemDialog(self)
}

2 个答案:

答案 0 :(得分:2)

您是正确的,代码不会等待此人输入数据并单击确定按钮。答案是使用完成处理程序。

// This is a slightly modified version of your code
func showAddItemDialog(view: UIViewController, completion: (text: String?) -> Void ) {

    var textOfTask = UITextField()
    var textValue = ""

    let diag = UIAlertController(title: "Add Task", message: "Enter a task name", preferredStyle: .Alert)
    diag.addTextFieldWithConfigurationHandler({ (textField) -> Void in })
    diag.addAction(UIAlertAction(title: "Add", style: .Default, handler: { (action) -> Void in
        textOfTask = diag.textFields![0] as UITextField
        textValue = textOfTask.text!

        addListItem(textValue)
        completion(text: textValue)
    }))

    diag.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in
        completion(text: nil)
    }))
    view.presentViewController(diag, animated: true, completion: nil)
}


// In the view controller
@IBAction func didPressAdd(sender: AnyObject) { 

    // Call it like this:
    showAddItemDialog(self) {
        (text) in
        // handle the result value here
        if let textUserEntered = text {
            // User entered some text and pressed OK
        }
        else {
            // User pressed cancel
        }
    }
}

答案 1 :(得分:1)

正如@nhgrif在评论中所说,你不能因为你的功能而返回一个值。一旦将警报发送到系统进行显示,并且在警报被绘制到屏幕之前,该功能就会立即返回。

在处理异步方法时,这是一个非常常见的初学者错误。

您需要重构showAddItemDialog函数以使用字符串参数进行完成闭包。在添加操作的闭包中,从警报字段中获取文本,然后调用传递给您的闭包,为其提供字符串。

然后当你调用showAddItemDialog函数时,传递一个闭包,它可以对你从用户收集的文本做任何你需要做的事情。