iOS - 逐个加载单元格

时间:2017-06-09 02:54:21

标签: ios objective-c swift uitableview uicollectionview

我想使用API​​ collectionView.insertItems(at:)逐个加载集合视图的单元格。网上有很多答案可以通过设置alpha内部willDisplayCell和其他方法(例如此处 - link的动画来实现此目的。然而,没有任何效果。使用collectionView.insertItems(at:)的原因是动画已内置,无需黑客攻击。

但是使用collectionView.insertItems(at:),我会收到错误,例如:

  

***由于未捕获的异常终止应用' NSInternalInconsistencyException',原因:'无效更新:无效   第0节中的项目数。包含在项目中的项目数   更新后的现有部分(5)必须等于数量   更新前的该部分中包含的项目(5),加号或减号   从该部分插入或删除的项目数(插入1个,   0已删除)并加上或减去移入或移出的项目数   该部分(0移入,0移出)。

这是我所拥有的一个例子,它如上所示崩溃,但它是一个开始我认为正确的方向(希望如此):

class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    /// This array is populated from a network call.
    let images = [Image]()

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        animateCells()
    }

    func animateCells() {
        let indexPaths = [IndexPath(item: 0, section: 0),
                          IndexPath(item: 1, section: 0),
                          IndexPath(item: 2, section: 0),
                          IndexPath(item: 3, section: 0),
                          IndexPath(item: 4, section: 0)]

        for indexPath in indexPaths {
            let delayTime = 0.1 + Double(indexPath.row) * 0.3

            delay(delayTime) {
                self.collectionView.performBatchUpdates({
                    self.collectionView.insertItems(at: [indexPath])
                }, completion: nil)
            }
        }
    }

    func delay(_ delay: TimeInterval, closure: @escaping () -> Void) {
        let when = DispatchTime.now() + delay
        DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
    }
}

// MARK: - UICollectionViewDataSource

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

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)

        return cell
    }
}

我看到的一个主要问题是我在return images.countnumberOfItemsInSection

有什么想法?

2 个答案:

答案 0 :(得分:1)

您是否尝试过延迟将元素附加到images

var images = Array(repeating: 0, count: 0)

delay(delayTime) {
     self.collectionView.performBatchUpdates({
                self.images.append(0)       
                self.collectionView.insertItems(at: [indexPath])
     }, completion: nil)
}

答案 1 :(得分:1)

我用你的代码做了一个演示并找到了你的错误

  

当您在集合视图中插入项目时,集合视图中已有5个项目位于该位置,因此您无法在其中插入新单元格,因为您的图像数组只有5个项目已经显示。

请查看以下工作代码 - >

    class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    //Array for collectionView
    var images :[UIImage] = []

    //This array will populate from network call
    var arrAllImagesFromNetwork : [UIImage] = Array(repeating: UIImage(named: "img1")!, count: 5)

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        animateCells()

    }

    func animateCells() {
        let indexPaths = [IndexPath(item: 0, section: 0),
                          IndexPath(item: 1, section: 0),
                          IndexPath(item: 2, section: 0),
                          IndexPath(item: 3, section: 0),
                          IndexPath(item: 4, section: 0)]



        for indexPath in indexPaths {
            let delayTime = 0.1 + Double(indexPath.row) * 0.3

            delay(delayTime) {

                self.images.append(self.arrAllImagesFromNetwork[indexPath.row])

                self.collectionView.performBatchUpdates({
                    self.collectionView.insertItems(at: [indexPath])
                }, completion: nil)
            }
        }
    }

    func delay(_ delay: TimeInterval, closure: @escaping () -> Void) {
        let when = DispatchTime.now() + delay
        DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
    }
}

// MARK: - UICollectionViewDataSource

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

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)

        return cell
    }
}