【问题标题】:swift - Correct way to pass data to UICollectionViewCellswift - 将数据传递给 UICollectionViewCell 的正确方法
【发布时间】:2020-09-27 11:20:16
【问题描述】:

我正在尝试创建自己的图书应用,并使用UICollectionView 列出所有图书。每个单元格的数据来自.plist 文件,我正在使用自定义flowLayout(稍后进行一些更改)。

所以现在我在滚动时遇到了延迟和滞后。我想我在将数据传递给单元格或初始化单元格时犯了错误。

.xib 和自定义类创建的单元格,只是一些布局和 UI:

class BookCoverCell: UICollectionViewCell {
    @IBOutlet weak var view1: UIView!
    @IBOutlet weak var view2: UIView!
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var darkRedView: UIView!
    @IBOutlet weak var lightRedView: UIView!
    @IBOutlet weak var readButton: UIButton!
    @IBOutlet weak var pageLabel: UILabel!    


    override func awakeFromNib() {
        super.awakeFromNib()
        clipsToBounds = true
        self.backgroundColor = UIColor(white: 1, alpha: 0.0)
        view1.layer.cornerRadius = 10
        view2.layer.cornerRadius = 10
        darkRedView.layer.cornerRadius = 10
        lightRedView.layer.cornerRadius = 10
    }    
} 

在 ViewController 的类中:

class MainVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UIScrollViewDelegate {


    @IBOutlet weak var collectionContainerView: UIView!
    @IBOutlet weak var collectionView: UICollectionView!

    var books: Array<Book>? {
        didSet {
            collectionView.reloadData()
        }
    }
    var flowLayout = UICollectionViewFlowLayout()
    override func viewDidLayoutSubviews() {        
        flowLayout = ZoomAndSnapFlowLayout()
        collectionView.collectionViewLayout = flowLayout
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionContainerView.backgroundColor = UIColor(white: 1, alpha: 0.0)
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(UINib(nibName: "BookCoverCell", bundle: nil), forCellWithReuseIdentifier: "BookCoverCell");
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        books = BookStore.sharedInstance.loadBooks(plist: "Books")        
    }

//MARK: UICollectionViewDelegate

    func numberOfSections(in collectionView: UICollectionView) -> Int {
      return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if let books = books {
            return books.count
        }
        return 0
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BookCoverCell", for: indexPath) as! BookCoverCell
        let book = books![indexPath.row]
        let cover = book.coverImage()!
        let color = book.getDominantColor()
        cell.view1.backgroundColor = color
        cell.imageView.image = cover
        cell.pageLabel.text = "Pages: 29"
        cell.readButton.setTitle("Read", for: .normal)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let book = books?[indexPath.row]
        print ("open")
    }

}

我的布局现在看起来像:

class ZoomAndSnapFlowLayout: UICollectionViewFlowLayout {


    var cellWidth = CGFloat()
    var cellHeight = CGFloat()
    var minLineSpacing = CGFloat()

    override init() {
        super.init()
        self.scrollDirection = .horizontal
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func prepare() {
        guard let collectionView = collectionView else { fatalError() }

        cellHeight = collectionView.frame.height * 0.8
        minLineSpacing = 200
        cellWidth = cellHeight

        itemSize = CGSize(width: cellWidth, height: cellHeight)

        let verticalInsets = (collectionView.frame.height - collectionView.adjustedContentInset.top - collectionView.adjustedContentInset.bottom - itemSize.height) / 2
        let horizontalInsets = (collectionView.frame.width - collectionView.adjustedContentInset.right - collectionView.adjustedContentInset.left - itemSize.width) / 2

        sectionInset = UIEdgeInsets(top: verticalInsets, left: horizontalInsets, bottom: verticalInsets, right: horizontalInsets)

        super.prepare()
    }
}

所以我很确定我的代码中有一些错误,但找不到它们((任何建议都会对我有所帮助!

更新: 所以首先谢谢! 我已经更改了我的代码并用最小的图像替换了一个非常大的图像,并且现在可以将主色简单地变为白色,并且事情已经变得更好了!

但是第一次滚动开始时会有小的滞后或延迟,并且只有第一个和第二个单元格,而它们正在滚动到屏幕的左边缘。之后,所有单元格都在两个方向(左/右)滚动而没有滞后,甚至前两个。

现在我的代码如下所示:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BookCoverCell", for: indexPath) as! BookCoverCell
        let book = books![indexPath.row]
        let cover = UIImage(named: "flag.png")
        let color = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
        cell.view1.backgroundColor = color
        cell.imageView.image = cover
        cell.pageLabel.text = "Pages: 29"
        cell.readButton.setTitle("Read", for: .normal)
        return cell
    }

更新 #2 删除

flowLayout = ZoomAndSnapFlowLayout()
collectionView.collectionViewLayout = flowLayout

to viewWillAppear() 也修复这些小滞后!!万岁!)

【问题讨论】:

  • coverImagegetDominantColor 有什么作用?我的猜测是,这些延迟至少是由这些电话引起的。其实,你为什么不使用 Instruments 来找出答案呢?
  • 可能的滞后:viewDidLayoutSubviews 是否被频繁调用? getDominantColor()coverImage() 代码?您是否尝试过使用 Instruments 和 Time Profiling?
  • @Sweeper 问题在于方法、大图像大小和在 viewDidLayoutSubviews 定义 layoutFlow

标签: ios swift uicollectionview uicollectionviewflowlayout


【解决方案1】:

阅读这篇关于时间分析和集合视图的文章:https://voxels.github.io/eliminating-collection-view-tearing-with-xcode-time-profiler-instrument

由于您的实现非常简单,因此可能出错的地方并不多,但您可能遇到了与文章作者相同的问题——图像本身非常大,需要阅读和阅读调整大小。

他们通过制作适当大小的图像版本解决了这个问题。

在你的情况下getDominantColor 在大图像上也会变慢(我假设它读取像素以获得主色。你还应该考虑缓存这个颜色而不是每次都重新计算它(如果你还没有这样做)。

【讨论】:

  • 感谢您对图片尺寸的建议!但是有一点滞后,请检查更新以发布,也许你发现了其他东西
  • 在正确的位置定义 layoutFlow 的另一个小修复 - 现在一切正常!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
  • 1970-01-01
  • 2017-07-01
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
相关资源
最近更新 更多