Swift 5 如何获取UIAlert内TextField绑定的UIPickerView选中值
解决方案
你可以通过临时持有弹窗内的分类输入框实现需求,具体修改步骤如下:
步骤1:新增临时存储属性
在你的ViewController类中新增一个可选的UITextField属性,用来持有弹窗内的分类输入框:
class ViewController: UIViewController { let todoItemCategory = ["Work", "Home", "Friends", "Buy stuff"] let pickerView = UIPickerView() // 新增这行 var categoryTextField: UITextField? // 其余原有代码保持不变 }
步骤2:将弹窗内的分类输入框赋值给全局属性
在创建弹窗第二个输入框的闭包中,新增赋值逻辑:
alert.addTextField { field in field.placeholder = "Select category" field.inputView = self.pickerView // 新增这行 self.categoryTextField = field }
步骤3:在PickerView选中回调中更新输入框内容
完善UIPickerViewDelegate的didSelectRow方法:
extension ViewController: UIPickerViewDelegate { func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { // 给分类输入框赋值选中的分类 categoryTextField?.text = todoItemCategory[row] // 可选:如果选中后需要自动收起选择器,新增下面这行 // categoryTextField?.resignFirstResponder() } }
步骤4:避免循环引用
在弹窗的取消、保存按钮回调中,将临时持有的输入框置空,释放内存:
// 取消按钮回调修改 alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { [weak self] _ in self?.categoryTextField = nil })) // 保存按钮回调修改 alert.addAction(UIAlertAction(title: "Save", style: .default, handler: { [weak self] _ in // 原有逻辑保持不变 guard let fields = alert.textFields, fields.count == 2 else { return } let itemTitleField = fields[0] let categoryField = fields[1] guard let itemTitle = itemTitleField.text, !itemTitle.isEmpty, let category = categoryField.text, !category.isEmpty else { print("Invalid entries") return } print(itemTitle) print(category) // 新增这行 self?.categoryTextField = nil }))
备选方案(无需新增全局属性)
如果你不想新增全局属性,可以通过获取当前第一响应者的方式拿到输入框,需要先添加一个UIResponder的扩展来获取当前第一响应者:
extension UIResponder { private static weak var currentFirstResponder: UIResponder? static func currentFirst() -> UIResponder? { currentFirstResponder = nil // 通过发送消息遍历所有响应者 UIApplication.shared.sendAction(#selector(findFirstResponder), to: nil, from: nil, for: nil) return currentFirstResponder } @objc private func findFirstResponder() { UIResponder.currentFirstResponder = self } }
之后直接在didSelectRow方法中使用即可:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { if let textField = UIResponder.currentFirst() as? UITextField { textField.text = todoItemCategory[row] } }
内容的提问来源于stack exchange,提问作者taisei.k
相关产品推荐
相关产品推荐

