代码之家  ›  专栏  ›  技术社区  ›  Paras Gorasiya

UICollectionViewCell重用导致UISwitch状态不正确

  •  3
  • Paras Gorasiya  · 技术社区  · 6 年前

    我很难找到解决这个问题的办法。 我正在使用 UISwitch UICollectionViewCell 我传递了一个布尔变量来设置开关。

    条件是所有电池一次只需打开一个开关。 但当我打开一个开关,另一个随机开关的颜色改变,这意味着它的状态改变。

    默认情况下,在情节提要中开关状态为“开”,即使我将其设置为“关”,也不会发生任何更改。

    我不明白为什么会这样。

    这是我的密码 cellForItemAtIndexPath

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AddEditItemPopupView.cellId, for: indexPath) as! DiscountCollectionViewCell
            cell.delegate = self
    
            let currentDiscount = allDiscounts[indexPath.item]
            let shouldApplyDiscount = updatedDiscountId == currentDiscount.id
            cell.updateCellWith(data: currentDiscount, applyDiscount: shouldApplyDiscount)
            return cell
        }
    

    以及细胞类的代码

    func updateCellWith(data: DiscountModel, applyDiscount: Bool) {
            let name = data.title.replacingOccurrences(of: "Discount ", with: "")
            self.titleLabel.text = String(format: "%@ (%.2f%%)", name, data.value)
            self.switchApply.isOn = applyDiscount
            self.switchApply.tag = data.id
        }
    

    数据源包含的对象 DiscountModel 看起来是这样的:

    {
        id: Int!
        title: String!
        value: Double!
    }
    

    @IBAction func switchValueChanged(_ sender: UISwitch) {
            if sender.isOn {
                self.delegate?.switchValueDidChangeAt(index: sender.tag)
            }
            else{
                self.delegate?.switchValueDidChangeAt(index: 0)
            }
        }
    

    视图控制器类中的委托方法:

    func switchValueDidChangeAt(index: Int) {
            self.updatedDiscountId = index
            self.discountCollectionView.reloadData()
        }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Paulw11    6 年前

    我建议对您的代码进行一些改进;

    • 重新加载整个集合视图有点麻烦
    • 由于可能不应用折扣,您可能应该为所选折扣使用可选的,而不是“0”
    • Tag 通常是有问题的

    我会用这样的方法:

    var currentDiscount: DiscountModel? = nil
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AddEditItemPopupView.cellId, for: indexPath) as! DiscountCollectionViewCell
        cell.delegate = self
    
        let item = allDiscounts[indexPath.item]
        self.configure(cell, forItem: item)
    
        return cell
    }
    
    func configure(_ cell: DiscountCollectionViewCell, forItem item: DiscountModel) {
        cell.switchApply.isOn = false
        let name = item.title.replacingOccurrences(of: "Discount ", with: "")
        self.titleLabel.text = String(format: "%@ (%.2f%%)", name, item.value)
    
        guard let selectedDiscount = self.currentDiscount else {
            return
        }
    
        cell.switchApply.isOn = selectedDiscount.id == item.id
    }
    
    func switchValueDidChangeIn(cell: DiscountCollectionViewCell, to value: Bool) {
        if value {
            if let indexPath = collectionView.indexPath(for: cell) {
               self.currentDiscount = self.allDiscounts[indexPath.item]
            }
        } else {
            self.currentDiscount = nil
        }
        for indexPath in collectionView.indexPathsForVisibleItems {
            if let cell = collectionView.cellForItem(at: indexPath) {
                self.configure(cell, forItem: self.allDiscounts[indexPath.item])
            }
        }
    }
    

    在你的牢房里:

    @IBAction func switchValueChanged(_ sender: UISwitch) {
        self.delegate?.switchValueDidChangeIn(cell:self, to: sender.isOn)
    }