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

iOS开发:点击TableViewCell时Picker显示在相邻Cell上的问题

UITableView唤起Picker位置错误问题解决

问题分析

点击UITableView Cell唤起Picker时,Picker出现在下一个Cell位置,核心原因是UITableView的Cell复用机制导致TextField的InputView关联混乱,再加上reloadCell操作进一步加剧了响应者状态的错位。

解决方案

1. 重置复用Cell的TextField状态

在ContactsTableViewCell中重写prepareForReuse方法,确保Cell复用时清除之前的响应者状态:

class ContactsTableViewCell: UITableViewCell {
    // 你的Cell现有代码...
    
    override func prepareForReuse() {
        super.prepareForReuse()
        // 取消TextField的第一响应者状态
        roleTextField.resignFirstResponder()
        // 按需重置TextField文本
        roleTextField.text = nil
    }
}

2. 优化角色选择后的更新逻辑

避免在选择角色后立即reload当前Cell,直接修改Cell的UI即可:

func didSelectRole(_ role: String?, forCell cell: ContactsTableViewCell) {
    guard let indexPath = contactsTableView.indexPath(for: cell) else {
        return
    }
    // 直接更新TextField文本,无需reload
    cell.roleTextField.text = role ?? "None"
    print("Selected role: \(role ?? \"None\") for contact at \(indexPath.row)")
}

如果业务必须要reload Cell,需先取消TextField的响应者状态:

func didSelectRole(_ role: String?, forCell cell: ContactsTableViewCell) {
    guard let indexPath = contactsTableView.indexPath(for: cell) else {
        return
    }
    // 先取消第一响应者,再执行reload
    cell.roleTextField.resignFirstResponder()
    contactsTableView.reloadRows(at: [indexPath], with: .automatic)
    print("Selected role: \(role ?? \"None\") for contact at \(indexPath.row)")
}

3. 确保每个Cell的TextField绑定独立Picker

在ContactsTableViewCell初始化时为每个TextField创建独立的Picker实例,避免复用导致的关联混乱:

class ContactsTableViewCell: UITableViewCell {
    let roleTextField = UITextField()
    private var pickerView: UIPickerView!
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupRoleTextField()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupRoleTextField()
    }
    
    private func setupRoleTextField() {
        pickerView = UIPickerView()
        // 配置Picker的数据源、代理等逻辑
        roleTextField.inputView = pickerView
        // 你的TextField布局代码...
    }
}

4. 确保唤起Picker时Cell位置准确

在点击Cell时,先将Cell滚动到可见区域,再唤起Picker,避免坐标计算错误:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // 滚动Cell到可见区域
    tableView.scrollToRow(at: indexPath, at: .none, animated: true)
    // 等待滚动完成后唤起Picker
    DispatchQueue.main.async {
        if let cell = tableView.cellForRow(at: indexPath) as? ContactsTableViewCell {
            cell.roleTextField.becomeFirstResponder()
        }
    }
}

内容的提问来源于stack exchange,提问作者Collins Muthomi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:13:22