我该怎么做:库的回调函数要等到用户从弹出菜单中选择之后才能返回

时间:2019-08-11 20:31:20

标签: ios swift

我在了解如何使用视图/委托和完成功能时遇到问题。

我使用具有回调的库-类似于: func youShouldChoose()-> String。

我愿意给用户一个选择,然后打开弹出窗口。但是我不明白如何返回选择的值。

我读到有关完成的内容。所以我尝试了这个:

func youShouldChoose() -> String {        
       askUser() 

       return self.valueForResult    //This line is executed earlier than askUser is finished
    }


func  askUser(){
          showAlert(completion: {(result)->Void in
           self.valueForResult = result
    })
}


func showAlert(completion:@escaping (_ result:String)->Void)
    {
        let alert = UIAlertController(...)
        alert.addAction(UIAlertAction(title: "Click", style: UIAlertAction.Style.default, handler: { action in
              completion(textField.text)
        }))
        alert.addTextField(configurationHandler: {(textField: UITextField!) in
            textField.placeholder = "Enter text:"
     })

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

我如何才能等到askUser()完全结束?有没有办法将完成后的价值返回给我的图书馆?

2 个答案:

答案 0 :(得分:0)

我找到了两种方法来解决此问题: 1.使用循环。显示视图直到标志为假

askUser() //we should set flag to true here  
while( flag == false ) {
    CFRunLoopRunInMode(CFRunLoopMode.defaultMode, 1, true);
}
return self.valueForResult 
  1. 使用信号量

    let semaphore = DispatchSemaphore(value: 0)
    askUser()   
    semaphore.lock()
    return self.valueForResult 
    

答案 1 :(得分:0)

这是一个示例解决方案(Swift 4.2 / 5.0):

func youShouldChoose(_ completion: @escaping ((String) -> Void)) {
    askUser(completion) // handing over the completion block to `askUser.

    // Alternative completion block execution:
    // askUser { (enteredText) in
    //     // This block is called when the "Click" action button on the alert was tapped.
    //     completion(enteredText)
    // }
}

func askUser(_ completion: @escaping ((String) -> Void)) {
    showAlert(completion) // handing over the completion block to `showAlert`.
}

func showAlert(_ completion: @escaping (String) -> Void) {
    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
    alert.addAction(UIAlertAction.init(title: "Click", style: .default, handler: { (_) in
        if let textField = alert.textFields?.first, let text = textField.text {
            completion(text) // -> handing over the text of the textField!
        } else {
            // No text field or text available. Something went wrong!
        }
    }))
    alert.addTextField { (textField) in
        textField.placeholder = "Enter text:"
    }
    self.present(alert, animated: true, completion: nil)
}

// How to use `youShouldChoose `: 
func foo() {
    youShouldChoose { (enteredText) in
        // This block is called when `youShouldChoose` is finished.
        print(enteredText) // -> prints the user's entered text.
        print("Hello")
    }
}