【问题标题】:Access input from UIAlertController从 UIAlertController 访问输入
【发布时间】:2014-08-02 01:57:12
【问题描述】:

我有一个 UIAlertController,当他们在 TouchID 屏幕上选择“输入密码”时会提示用户。在屏幕上呈现后如何恢复用户的输入?

let passwordPrompt = UIAlertController(title: "Enter Password", message: "You have selected to enter your passwod.", preferredStyle: UIAlertControllerStyle.Alert)
passwordPrompt.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Default, handler: nil))
passwordPrompt.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))

passwordPrompt.addTextFieldWithConfigurationHandler({(textField: UITextField!) in
                        textField.placeholder = "Password"
                        textField.secureTextEntry = true
                        })

presentViewController(passwordPrompt, animated: true, completion: nil)

我知道 OK 按钮可能应该有一个处理程序,但现在这段代码并没有真正做任何事情,但我想通过 println 显示文本字段的输出。这实际上只是一个测试应用程序,供我学习 Swift 和一些新的 API 内容。

【问题讨论】:

  • 你要设置控制器的delegate,然后实现委托回调
  • 我认为 UIAlertController 没有委托。文档中似乎没有提到它。
  • 哦,不是我的错,我把它和UIAlertView 混淆了。您应该为每个按钮将一个函数传递给handler。处理程序将在按下时调用
  • 处理程序如何访问 UITextField?闭包返回 Void 并且 UITextField 的范围在闭包内。处理程序将代表单击“确定”或“取消”的操作,但我不明白这将如何让我查询输入的文本。
  • 处理程序的签名是:handler: ((UIAlertAction!) -> Void)!),因此发送者确实会被传入。您必须访问passwordPrompt.textFields 才能在处理程序中获取输入的文本。

标签: swift ios8 uialertcontroller


【解决方案1】:

我知道已经发布了 cmets 来回答这个问题,但答案应该明确解决方案。

@IBOutlet var newWordField: UITextField
func wordEntered(alert: UIAlertAction!){
    // store the new word
    self.textView2.text = deletedString + " " + self.newWordField.text
}
func addTextField(textField: UITextField!){
    // add the text field and make the result global
    textField.placeholder = "Definition"
    self.newWordField = textField
}

// display an alert
let newWordPrompt = UIAlertController(title: "Enter definition", message: "Trainging the machine!", preferredStyle: UIAlertControllerStyle.Alert)
newWordPrompt.addTextFieldWithConfigurationHandler(addTextField)
newWordPrompt.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Default, handler: nil))
newWordPrompt.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: wordEntered))
presentViewController(newWordPrompt, animated: true, completion: nil)

这会显示一个带有文本字段和两个操作按钮的提示。完成后它会读取文本字段。

【讨论】:

  • 您也可以使用对newWordField weak var newWordField: UITextField 的弱引用,这样您就不会拥有该文本字段,因为它必须已经被警报控制器强烈指出`
【解决方案2】:

在你的闭包中这样做:

let tf = alert.textFields[0] as UITextField

Here is a gist

【讨论】:

  • 如果你使用这种方法,请确保将alert捕获为unowned,以避免引用循环,从而导致内存泄漏。
  • @AshFurrow 你能详细说明一下吗?如何将alert 捕获为unowned
  • 实际上,如果您查看 Apple 的 UICatalog 示例 (Swift/UICatalog/AlertControllerViewController.swift),他们会在您配置文本字段时为 handleTextFieldTextDidChangeNotification 添加一个 NSNotificationCenter 观察者。
  • 当然,这也有效。我的意思是,如果您从操作处理程序闭包中访问alert.textFields 数组,您将有一个引用循环。您需要的文档标题为“Resolving Strong Reference Cycles for Closures”。
  • textFields 是可选的,至少在 Xcode 6.2 中是这样。所以应该是let tf = alert.textFields![0] as UITextField
【解决方案3】:

我写了一个blog post 来探索新的 API。你可以在闭包中捕获一个局部变量,你就可以开始了。

var inputTextField: UITextField?
let passwordPrompt = UIAlertController(title: "Enter Password", message: "You have selected to enter your password.", preferredStyle: UIAlertControllerStyle.Alert)
passwordPrompt.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Default, handler: nil))
passwordPrompt.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { (action) -> Void in
    // Now do whatever you want with inputTextField (remember to unwrap the optional)
}))
passwordPrompt.addTextFieldWithConfigurationHandler({(textField: UITextField!) in
    textField.placeholder = "Password"
    textField.secureTextEntry = true
    inputTextField = textField
 })

presentViewController(passwordPrompt, animated: true, completion: nil)

这样可以避免视图控制器上出现不必要的属性。

【讨论】:

【解决方案4】:

我将 Ash Furrow's answer 移植到 Swift 3。

    var inputTextField: UITextField?
    let passwordPrompt = UIAlertController(title: "Enter Password", message: "You have selected to enter your password.", preferredStyle: UIAlertControllerStyle.alert)
    passwordPrompt.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default, handler: nil))
    passwordPrompt.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) -> Void in
        // Now do whatever you want with inputTextField (remember to unwrap the optional)
    }))
    passwordPrompt.addTextField(configurationHandler: {(textField: UITextField!) in
        textField.placeholder = "Password"
        textField.isSecureTextEntry = true
        inputTextField = textField
    })

    present(passwordPrompt, animated: true, completion: nil)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多