You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:45:02