在快速滚动collectionview时,第一行数据在最后一行重复

Posted

技术标签:

【中文标题】在快速滚动collectionview时,第一行数据在最后一行重复【英文标题】:While fast scrolling collectionview the first row data duplicate in the last row 【发布时间】:2016-12-06 18:58:27 【问题描述】:

我想制作一个设计看起来像应用商店的应用程序,所以我按照让我们构建该应用程序教程来了解如何构建它,结果非常好,当我在我的设备上测试它时,似乎当我快速滚动集合视图,第一行中的数据发生在最后一行,当再次快速向上滚动时,应该在最后一行中的数据我在第一行中找到它,当我左右滚动时当单元格离开屏幕时,它会重新更新为正确的数据,但是当再次快速上下滚动时,第一行和最后一行之间的数据会变得疯狂。 我在代码末尾添加了图像。我花了 5 天时间试图解决这个问题,但一点运气都没有在代码中但没有运气,我非常感谢您提供的任何帮助,谢谢

*更新 在@Joe Daniels 回答之后,所有数据都是主食并且工作正常,除了快速滚动时它仍然会发疯的图像,但它会在停止滚动到正确图像的 7/8 秒后返回

第一个包含垂直collectionview的类 我使单元格的宽度等于视图的宽度,我尝试了 cell.tag == index-path.row 解决方案,但它不起作用

        class HomePageVC: UIViewController  ,  UICollectionViewDataSource , UICollectionViewDelegate , UICollectionViewDelegateFlowLayout ,SWRevealViewControllerDelegate 

override func viewDidLoad() 
    super.viewDidLoad()
     mainProductsRow.delegate = self
    mainProductsRow.dataSource = self



   func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 

            if let count = productCategory?.count 
            return count + 1
        
        return 0



func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    if indexPath.row == 0 
        let   cell  = collectionView.dequeueReusableCell(withReuseIdentifier: LargeHomeCategoriesCell.identifier, for: indexPath) as! LargeHomeCategoriesCell
        cell.categoriesHomePageVC = self
        cell.catIndexPath = indexPath.row
        cell.productCategories = productCategory
        cell.seeMore.addTarget(self, action: #selector(self.seeMoreCat(_:)), for: UIControlEvents.touchUpInside)
        return cell
    
        let   cell  = collectionView.dequeueReusableCell(withReuseIdentifier: "RowCell", for: indexPath) as! HomeCategoriesCell

        cell.categoriesHomePageVC = self
        cell.catIndexPath = indexPath.row
    cell.seeMore.tag = (indexPath.row - 1 )
    cell.seeMore.addTarget(self, action: #selector(self.seeMore(_:)), for: UIControlEvents.touchUpInside)
 //   cell.tag = indexPath.row - 1
    cell.productCategory = nil
    //if cell.tag == indexPath.row - 1
        cell.productCategory = productCategory?[indexPath.row - 1 ]

 //   
        return cell



**第二个类,包含第一个collectionview单元格中的水平collectionview ** 在 cell-for-item-At-index-Path 中,当视图加载它打印 0 、 1 、2 并且没有打印最后一个索引 '3' 并且同样的事情再次发生时,我打印了 index-path.row当我滚动到集合视图的末尾时

class HomeCategoriesCell: UICollectionViewCell , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout , UICollectionViewDelegate




@IBOutlet weak var seeMore: UIButton!
@IBOutlet weak var categorytitle: UILabel!
@IBOutlet weak var productsCollectionView: UICollectionView!

let favFuncsClass = FavItemsFunctionality()
let onCartFuncsClass = OnCartFunctionality()

var productCategory : ProductCategories? 
    didSet 
        if let categoryTitle = productCategory?.name 
            categorytitle.text = categoryTitle
        
    

  override func awakeFromNib() 
    recivedNotification()

    productsCollectionView.delegate = self
    productsCollectionView.dataSource = self
    productsCollectionView.backgroundColor = UIColor.clear


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    if let count = productCategory?.products?.count 
        return count
    
    return 0

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    print(indexPath.row)
    let   cell  = collectionView.dequeueReusableCell(withReuseIdentifier: "HProductCell", for: indexPath) as! HomeProductCell
    cell.tag = indexPath.row

    cell.productImage.image = #imageLiteral(resourceName: "PlaceHolder")
    cell.productTitle.text = nil
    cell.productPrice.text = nil
    cell.discountLabel.text = nil
    cell.preDiscountedPrice.text = nil
    cell.favButton.setImage(UIImage(named:"Heart_icon"), for: UIControlState.normal)
    cell.addToCart.setImage(UIImage(named:"cart"), for: UIControlState.normal)
    cell.configCell(products: nil)
    if cell.tag == indexPath.row 
        cell.configCell(products: productCategory?.products?[indexPath.item])
    
    cell.catNum = indexPath.row

    return cell

    // Thanks to Joe Daniels i added this code and my nightmare become way less scary :P 
      override func prepareForReuse() 
    super.prepareForReuse()
    productsCollectionView.reloadData()
  


产品单元 我尝试了 prepare-For-Reuse() 并将所有数据重置为零,但仍然没有工作

  class HomeProductCell: UICollectionViewCell 

func configCell(products :productDetails?)
      if let title = products?.name 
        self.productTitle.text = title
    else   self.productTitle.text = nil

    if let price = products?.price 
        self.productPrice.text = "\(price)"
    else  self.productPrice.text = nil 

    

  override func prepareForReuse() 
    super.prepareForReuse()
    self.productImage.image = #imageLiteral(resourceName: "PlaceHolder")
    productTitle.text = nil
    productPrice.text = nil
    discountLabel.text = nil
    preDiscountedPrice.text = nil
    favButton.setImage(UIImage(named:"Heart_icon"), for: UIControlState.normal)
    addToCart.setImage(UIImage(named:"cart"), for: UIControlState.normal)


我截取了这个案例的屏幕截图,你可以找到它 here

【问题讨论】:

【参考方案1】:

内部 collectionView 无法知道它离开了屏幕。在prepareForReuse中做一个reload

【讨论】:

我试过了,它可以像魔术一样处理字符串数据,但是快速滚动时图像会丢失并复制并显示在错误的单元格中,但它会在大约 8 / 9 秒后变为正确的图像但毫无疑问你救了我非常感谢你^-^。你知道如何防止图像出现这种故障吗?【参考方案2】:

在经历了 15 天的痛苦 xD 之后,我找到了对我有用的完美解决方案 xD 我使用了这个库 (https://github.com/rs/SDWebImage)。

要快速使用它,请将此行放在您的桥接头中

#import <SDWebImage/UIImageView+WebCache.h>

在 collectionViewCell 中我使用了这一行

self.productImage.sd_setImage(with: myUrl , placeholderImage: UIImage(named:"yourPlaceHolderImage")

【讨论】:

以上是关于在快速滚动collectionview时,第一行数据在最后一行重复的主要内容,如果未能解决你的问题,请参考以下文章

快速旋转 UIColectionView 时的水平滚动

swift 2中Collectionview多个部分的不同滚动方向

滚动时应用 CollectionView layerMask “抖动”

如何滚动到第一个单元格,同时在 CollectionView 上滑动最后一个单元格?

UICollectionview 动态高度问题

奇怪的错误,collectionView 视图滚动到倒数第二条消息,当试图滚动到底部