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

UICollectionView不保留UITextField输入内容问题求助

解决嵌套UICollectionView中文本输入框内容丢失的问题

这个问题其实是UICollectionView单元格复用机制导致的——当你滚动MainCollectionView时,离开屏幕的MainCell会被回收复用,它内部的NestedCollectionView也会跟着被重置,而你之前输入的文本只存在于被回收的NestedCell的TextField里,自然就丢失了。核心解法是用数据模型保存输入状态,让UI始终从数据源读取内容,具体步骤如下:

  • 第一步:为嵌套条目创建独立的数据模型
    不要再依赖控件保存输入内容,给每个NestedCell创建一个数据模型,用来记录它的类型(Label/TextField)和当前文本:

    enum NestedItemType {
        case label
        case textField
    }
    
    struct NestedItem {
        var type: NestedItemType
        var content: String // 这里存默认值或用户输入的文本
    }
    

    同时,MainCollectionView的数据源要改成保存每个MainCell对应的嵌套数据数组,比如:var mainDataSource: [[NestedItem]] = [],每个元素对应一个MainCell的NestedCollectionView数据。

  • 第二步:让NestedCell支持数据绑定与回调
    在NestedCell里添加配置方法,从数据模型读取内容显示;同时添加回调,在文本变化时同步更新数据模型:

    class NestedCollectionViewCell: UICollectionViewCell {
        @IBOutlet weak var displayLabel: UILabel!
        @IBOutlet weak var inputTextField: UITextField!
        
        // 文本变化时的回调,用来更新数据模型
        var onTextChanged: ((String) -> Void)?
    
        override func awakeFromNib() {
            super.awakeFromNib()
            // 监听文本输入变化
            inputTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
            // 监听编辑结束,确保最后一次输入被同步
            inputTextField.addTarget(self, action: #selector(textFieldDidEndEdit(_:)), for: .editingDidEnd)
        }
    
        // 用数据模型配置cell
        func configure(with item: NestedItem) {
            displayLabel.isHidden = item.type != .label
            inputTextField.isHidden = item.type != .textField
            inputTextField.text = item.content
            displayLabel.text = item.content
        }
    
        @objc private func textFieldDidChange(_ textField: UITextField) {
            onTextChanged?(textField.text ?? "")
        }
    
        @objc private func textFieldDidEndEdit(_ textField: UITextField) {
            onTextChanged?(textField.text ?? "")
        }
    }
    
  • 第三步:在MainCell中绑定数据与回调
    MainCell持有自己对应的嵌套数据数组,配置NestedCollectionView时,把数据传给NestedCell,并设置回调更新数据源:

    class MainCollectionViewCell: UICollectionViewCell {
        @IBOutlet weak var nestedCollectionView: UICollectionView!
        var nestedItems: [NestedItem] = [] {
            didSet {
                nestedCollectionView.reloadData()
            }
        }
    
        override func awakeFromNib() {
            super.awakeFromNib()
            nestedCollectionView.dataSource = self
            nestedCollectionView.delegate = self
        }
    }
    
    extension MainCollectionViewCell: UICollectionViewDataSource {
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return nestedItems.count
        }
    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "NestedCell", for: indexPath) as! NestedCollectionViewCell
            let item = nestedItems[indexPath.item]
            cell.configure(with: item)
            
            // 设置回调,实时更新数据模型
            cell.onTextChanged = { [weak self] newText in
                guard let self = self else { return }
                self.nestedItems[indexPath.item].content = newText
            }
            return cell
        }
    }
    
  • 第四步:配置MainCollectionView的数据源
    在MainCollectionView的cellForItemAt方法中,把对应的嵌套数据传给MainCell:

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MainCell", for: indexPath) as! MainCollectionViewCell
        cell.nestedItems = mainDataSource[indexPath.item]
        return cell
    }
    

这样一来,不管MainCell怎么被复用,NestedCollectionView都会从数据源中读取最新的文本内容,用户输入的内容也会实时同步到数据模型里,滚动后自然不会丢失了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:20:16