UICollectionViewCell 重用导致不正确的 UISwitch 状态

     2023-02-23     78

关键词:

【中文标题】UICollectionViewCell 重用导致不正确的 UISwitch 状态【英文标题】:UICollectionViewCell reuse causing incorrect UISwitch state 【发布时间】:2019-01-26 07:00:51 【问题描述】:

我无法找到解决此问题的方法。 我在UICollectionViewCell 中使用UISwitch,并且我正在传递一个布尔变量来设置开关。

条件是所有单元中一次只有一个开关必须打开。 但是当我打开一个开关时,另一个随机开关的色调会发生变化,这意味着它的状态发生了变化。

默认情况下,故事板中的开关状态为 ON,即使我将其设置为 OFF,也没有任何变化。

我不知道为什么会这样。

这是我的 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!

cell类内的开关值改变方法:

@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()
    

【问题讨论】:

如果在没有滚动的情况下发生这种情况,则可能不是单元格重用。它是静态的还是动态的集合视图? 还有,什么是switchApply? @Chris switchApply 是 collectionViewCell 中 UISwitch 的一个出口。它是一个动态集合视图,当前仅包含 4 个适合 collectionView 宽度的单元格,是的,这是在不滚动的情况下发生的。那么是什么导致了这个问题呢? 我觉得这两行可能是问题所在(但不确定):let currentDiscount = ...let shouldApplyDiscount = ... 你所做的有些问题。当您单击开关时,它会启动动画,但您会立即重新加载单元格,重置isOn,因此取消动画。我会尝试if switchApply.isOn != applyDiscount switchApply.isOn = applyDiscount DispatchQueue.main.async self.switchApply.isOn = applyDiscount 。一种可能的解决方案是禁用开关上的交互并改为处理整个单元格上的点击(选择)。 【参考方案1】:

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

重新加载整个集合视图有点像霰弹枪 由于可能不应用折扣,因此您可能应该为您选择的折扣使用可选项,而不是“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)

【讨论】:

UICollectionViewCell 重用问题

】UICollectionViewCell重用问题【英文标题】:UICollectionViewCellreuseissue【发布时间】:2014-01-1010:44:59【问题描述】:我有一个故事板,我的一个viewController有一个CollectionView。我有一个原型单元格,里面有一个标签。我为该原型单元创... 查看详情

带有 UICollectionViewCell 的可重用 UITableViewCell

】带有UICollectionViewCell的可重用UITableViewCell【英文标题】:ReusableUITableViewCellwithUICollectionViewCell【发布时间】:2018-09-2010:53:02【问题描述】:代码:functableView(_tableView:UITableView,cellForRowAtindexPath:IndexPath)->UITableViewCell 查看详情

可重用的 UICollectionViewCell 不刷新

】可重用的UICollectionViewCell不刷新【英文标题】:ReusableUICollectionViewCelldoesn\'trefreshing【发布时间】:2017-01-1106:29:25【问题描述】:我的UICollectionViewCell在情节提要中有一个按钮,并从文档目录中动态设置按钮数量的背景图像,从... 查看详情

重用 UICollectionView 中的单元格时,会短暂显示重用 UICollectionViewCell 的旧内容

】重用UICollectionView中的单元格时,会短暂显示重用UICollectionViewCell的旧内容【英文标题】:TheoldcontentsofareusedUICollectionViewCellarebrieflydisplayedwhenreusingcellsinaUICollectionView【发布时间】:2013-04-2922:49:58【问题描述】:我正在使用UICollec... 查看详情

注册大量 UICollectionViewCell 类以在 UICollectionView 中重用

】注册大量UICollectionViewCell类以在UICollectionView中重用【英文标题】:RegisteringalotofUICollectionViewCellclassesforreuseinaUICollectionView【发布时间】:2018-04-1111:04:23【问题描述】:我正在关注AdvancedUserInterfaceswithCollectionViewsWWDC会议,其中Appl... 查看详情

带有重用标识符的 UICollectionViewCell 初始化

】带有重用标识符的UICollectionViewCell初始化【英文标题】:UICollectionViewCellinitwithreuseIdentifier【发布时间】:2015-02-2019:03:00【问题描述】:我有一个自定义UICollectionViewCell,我通过像这样注册它从我的视图控制器中取出它[self.calenda... 查看详情

照片框架和可重用的 UICollectionViewCell

】照片框架和可重用的UICollectionViewCell【英文标题】:PhotosframeworkandreusableUICollectionViewCell【发布时间】:2016-01-2916:03:48【问题描述】:我有一个UICollectionView来显示带有Photos框架的设备相册中的照片。照片显示正确,但如果我快... 查看详情

带有 UIProgressView 的自定义 UICollectionViewCell 在重用单元格上显示 progressView

】带有UIProgressView的自定义UICollectionViewCell在重用单元格上显示progressView【英文标题】:CustomUICollectionViewCellwithUIProgressViewshowsprogressViewonreusedcells【发布时间】:2013-06-0417:21:19【问题描述】:我将UICollectionViewCell子类化,因为我想... 查看详情

iOS - 图像未加载到可重用的 UICollectionViewCell 上

】iOS-图像未加载到可重用的UICollectionViewCell上【英文标题】:iOS-ImagesnotloadingonreusableUICollectionViewCell\'s【发布时间】:2012-11-2610:06:07【问题描述】:您好,我有一个问题,如果可能的话,我将不胜感激。我有一个应用程序,它有... 查看详情

UICollectionViewCell 阴影导致小滞后

】UICollectionViewCell阴影导致小滞后【英文标题】:UICollectionViewCellshadowcausessmalllag【发布时间】:2015-12-2122:54:33【问题描述】:在我的UICollectionView中向下滚动时,它会滞后,这是由以下原因引起的:imageCell?.backgroundColor=UIColor.whiteC... 查看详情

子类化 UICollectionViewCell 导致永远不会被选中

】子类化UICollectionViewCell导致永远不会被选中【英文标题】:SubclassingUICollectionViewCellleadstoneverbeingselected【发布时间】:2013-03-2220:00:50【问题描述】:我尝试子类化UICollectionViewCell并从nib文件加载:-(id)initWithFrame:(CGRect)frameself=[supe... 查看详情

带有界面生成器的 UICollectionViewCell

】带有界面生成器的UICollectionViewCell【英文标题】:UICollectionViewCellwithInterfaceBuilder【发布时间】:2014-12-1508:41:51【问题描述】:我在InterfaceBuilder中有以下nib设置,其中包含我的viewController的主视图(带有UICollectionView)以及标题... 查看详情

从 XIB 加载时 UICollectionViewCell 导致崩溃

】从XIB加载时UICollectionViewCell导致崩溃【英文标题】:UICollectionViewCellcausingcrashwhenloadingfromXIB【发布时间】:2014-10-1714:25:17【问题描述】:我有一个UICollectionViewCell子类,它现在只显示一个带有背景颜色的UIView子视图,以表明它就... 查看详情

UICollectionViewCell 中图像的异步加载导致标签消失

】UICollectionViewCell中图像的异步加载导致标签消失【英文标题】:AsynchronousloadingofimageinUICollectionViewCellcauseslabelstodisappear【发布时间】:2018-03-1222:34:23【问题描述】:我正在开发一个照片库应用程序,它基本上由一个导航控制器... 查看详情

Swift 3:以编程方式调整 UICollectionViewCell 的大小会导致单元格重叠

】Swift3:以编程方式调整UICollectionViewCell的大小会导致单元格重叠【英文标题】:Swift3:ResizingUICollectionViewCellprogrammaticallycausescellstooverlap【发布时间】:2016-08-2020:12:03【问题描述】:我正在尝试创建一个UICollectionView,其下方有3个... 查看详情

将 UICollectionViewCell 加载到 UIView

】将UICollectionViewCell加载到UIView【英文标题】:loadUICollectionViewCelltoUIView【发布时间】:2015-10-0510:45:27【问题描述】:我试图将UICollectionViewCell从.xib加载到UICollectionView,它也在.xib中的可重用UIView中。这个UIView将被加载到更多的UIV... 查看详情

uitableviewcell重用导致控件多次加载去除cell重用导致视图控件多次加载问题(代码片段)

原因UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,当cell滚出屏幕时,会将滚出屏幕的单元格放入重用的queue中,当某个未在... 查看详情

重用滤镜导致GPUImage黑屏

】重用滤镜导致GPUImage黑屏【英文标题】:ReusingfilterCausesblackscreeninGPUImage【发布时间】:2012-11-0509:49:47【问题描述】:我创建了一组GPUImageToneCurveFilter并存储在一个数组中。首先,在选择任何过滤器后,我使用GPUImageVideoCamera为所... 查看详情