2017-06-09 13 views
1

API collectionView.insertItems(at:)を使用して、コレクションビューのセルを1つずつロードします。オンラインで多くの答えが得られます。このセルには、のセルのalphaと他の方法をアニメーション化します。たとえば、linkです。しかし、何も完璧に動作しません。 collectionView.insertItems(at:)を使用する理由は、アニメーションが既に組み込まれており、ハックは必要ないからです。 、その理由iOS - セルを1つずつロードする

***「NSInternalInconsistencyException」キャッチされない例外によりにアプリを終了:「無効な更新:セクション0内の項目の無効 数番号を

しかしcollectionView.insertItems(at:)を使用して、私は次のようなエラーが出ますupdate(5)の後の 既存のセクションに含まれるアイテムの数は、更新(5)前にそのセクションに含まれている アイテムの数と同じでなければなりません(プラスまたはマイナス )挿入され、 が削除された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.countの中にnumberOfItemsInSectionの中にいます。

どのような考えですか?

+0

あなたは正しいものとして任意の答えを選択してくださいだろう。 –

+0

@GovindPrajapati答えはまだ試していない、すぐになります! – JEL

答えて

1

あなたのコレクションビュー内の項目を挿入しているとき、私はあなたが挿入することはできませんので、その位置にあなたのコレクションビューでの5つの項目がすでに存在している

をあなたのコードで1つのデモを作り、自分の間違いを発見しましたあなたの画像アレイには既に表示されている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 
    } 
} 
+0

なぜ 'self.images.append(indexPath.row)'をやっていますか?配列 'images'は実際のオブジェクトを対象としていますので、' let images = [Image]() 'を実行することでコードを変更しました。申し訳ありませんが明らかでない場合。この回答はまだ有効ですか? – JEL

+0

そのためには、2つの配列を1つ取って、ネットワークコールから受信したすべてのイメージを格納し、1つをコレクションビューに取り込みます。編集した解答を見てください。 –

+0

ありがとうございました!できます – JEL

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) 
} 
+0

2つの異なる配列を何らかの形で連動させる方が良いでしょうか?実際の配列に 'append''ingするのではなく、わからない – JEL

+0

実際のオブジェクトを使用するようにコードをリファクタリングしてもらえますか?私は私の質問をより明確にするように更新したので、 'var images = Array(繰り返し:0、count:10)'の代わりに 'let images = [Image]()'を使うようになりました。 'Image'の配列はネットワーク呼び出しから来ます。 – JEL

関連する問題