【问题标题】:UICollectionView IssueUICollectionView 问题
【发布时间】:2018-08-06 13:30:19
【问题描述】:

Xcode 10 测试版 5,iOS 12.0 16A5339e 我使用以下代码在我的应用程序中使用 UICollectionView:

extension MainWindowViewController: UICollectionViewDataSource, UICollectionViewDelegate {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return itemMenuArray.count
}

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

    if let itemCell = collectionView.dequeueReusableCell(withReuseIdentifier: "main_menu_cell", for: indexPath) as? MainWindowCollectionViewCell {

        let item = itemMenuArray[indexPath.row]
        itemCell.refresh(item)

        return itemCell
    }

    return UICollectionViewCell()
}

问题是,当我滚动 CollectionView 时,方法 .refresh 会针对单独的单元格执行。所以每次我滚动到它的方向时,屏幕外的单元格都会更新,有时会导致错误的单元格颜色。有什么想法可以解决这个问题吗?

.refresh 代码(我在我的自定义单元类中使用它):

public func refresh(_ menu: Menu) {

    Title.text = menu.name

    if let image = menu.img {
        Image.image = UIImage(named: image)
    }

    print(SubscriptionTitle.text!)

    self.setupCellAppearance(firstColor: UIColor(hexString: (menu.firstColor)!), secondColor: UIColor(hexString: (menu.secondColor)!))

}

setupCellAppearance代码:

func setupCellAppearance(firstColor: UIColor, secondColor: UIColor) {        
    // Setting up the gradient for each cell
    clipsToBounds = true
    let gradientLayer = CAGradientLayer()
    gradientLayer.colors = [firstColor.cgColor, secondColor.cgColor]
    gradientLayer.frame = self.bounds
    gradientLayer.startPoint = CGPoint(x: 0, y: 0)
    gradientLayer.endPoint = CGPoint(x: 1, y: 0)
    gradientLayer.cornerRadius = 10.0
    self.layer.insertSublayer(gradientLayer, at: 0)

    // Setting up the corner radius and shadows for each cell
    self.layer.shadowColor = firstColor.cgColor
    self.layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
    self.layer.shadowRadius = 10
    self.layer.shadowOpacity = 0.5
    self.layer.masksToBounds = false;
    self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).cgPath        
}

【问题讨论】:

  • 显示setupCellAppearance方法
  • 我编辑了问题
  • 每次在cellForItemAtIndexPath 中,您调用refresh() 时调用self.layer.insertSublayer()。我真的希望你删除 prepareForReuse() 中的这些层,因为单元格 (UITableViewCell/UICollectionViewCell) 被重复使用。

标签: ios swift xcode uicollectionview


【解决方案1】:

发生的事情是cellForItemAt 重用单元格,因此每次重用单元格时可能已经有渐变层,并且您正在尝试添加新的渐变以便创建不同的颜色。因此,如果该层已经存在,则需要删除该层,以删除具有某些唯一名称的 CAGradientLayer 的层集 name 属性,然后在插入该名称的层检查层之前,如果存在,则将其删除。

func setupCellAppearance(firstColor: UIColor, secondColor: UIColor) {

    //Check gradient is already exist
    for layer in self.layer.sublayers ?? [] {
        if layer.name == "BGGradient" {
            layer.removeFromSuperlayer()
            break
        }
    }

    // Setting up the gradient for each cell
    clipsToBounds = true
    let gradientLayer = CAGradientLayer()

    //set name property of gradient layer
    gradientLayer.name = "BGGradient"
    gradientLayer.colors = [firstColor.cgColor, secondColor.cgColor]
    gradientLayer.frame = self.bounds
    gradientLayer.startPoint = CGPoint(x: 0, y: 0)
    gradientLayer.endPoint = CGPoint(x: 1, y: 0)
    gradientLayer.cornerRadius = 10.0
    self.layer.insertSublayer(gradientLayer, at: 0)

    // Setting up the corner radius and shadows for each cell
    self.layer.shadowColor = firstColor.cgColor
    self.layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
    self.layer.shadowRadius = 10
    self.layer.shadowOpacity = 0.5
    self.layer.masksToBounds = false;
    self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).cgPath

}

【讨论】:

  • @MrBlazOn 欢迎朋友 :)
猜你喜欢
  • 1970-01-01
  • 2016-03-09
  • 2013-04-07
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多