2017-10-25 19 views
0

ユーザーが連絡先を選択した後で、単一のセルのみを再ロードしたい(method didSelect contact)セル内のアイテムの数が増えると、プロセスが遅くなります。私もDispatchQueue.main.async { code }に実装しようとしていますが、ロードにはまだ時間がかかります。Swift - UICollectionView reloadItemsが長すぎる

cellForItemAtとnoOfItemInSection(AddCell) - 総細胞4

var indexPaths = [IndexPath]() 

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    indexPaths.append(indexPath) 

    if indexPath.item == 1 { 
     let addCell = collectionView.dequeueReusableCell(withReuseIdentifier: CellId, for: indexPath) as! AddCell 
     addCell.btnAdd.addTarget(self, action: #selector(handleOpenContact), for: .touchUpInside) 
     addCell.invitees = invitees 
     return addCell 
    } 
} 

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 4 
    } 

cellForItemAtとnoOfItemInSection(SubAddCell)

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: subAddId, for: indexPath) as! SubAddCell 
     cell.delegate = self 
     cell.invitee = invitees[indexPath.item] 
     return cell 
    } 

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

didSelect(ContactPicker)

func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) { 
     let invitee = Invitee() 
     invitee.name = contact.givenName 

     if contact.isKeyAvailable(CNContactPhoneNumbersKey) { 
      for phoneNumber: CNLabeledValue in contact.phoneNumbers { 
       let a = phoneNumber.value 
       print("\(a.stringValue)") 
       invitee.phoneNo = a.stringValue 
      } 
     } 
     self.invitees.append(invitee) 

     for index in self.indexPaths { 
      if index == [0, 0] { 
       print(index) 
       self.collectionView?.reloadItems(at: [index]) 
      } 
     } 
    } 

メソッドでindexPathsの値を取得しています。参加者に5つのアイテムが含まれている場合、print(index)は19の値を出力します。どうしてか分かりません。以下はイメージです。

enter image description here

UI

reloadItemsを最適化する方法

enter image description here

のデザイン?

本当にありがとうございます。どうもありがとう。

+0

あなたは 'cellForItemAtIndexPath'メソッドの残りの部分を記述できますか?あなたはインデックス1のセルを扱うことを示しているにすぎませんが、明らかに19のセルが使用されています。残りの方法は何ですか? – murphguy

+0

@murphguy、それはわずか4セルでした。その特定のセルには、その内部に 'UICollectionView'があります。私は質問を更新しました。 – Nizzam

+0

あなたの挑戦はうそです。折りたたみ可能なセルのアニメーション/処理はかなり重いです。したがって、それは依存しています:セル内でオートレイアウトを使用するかどうかセルダイナミックの内容ですか?別のスレッドを使って画像を非同期的に読み込んでいますか?これらの3つの質問は、あなたのアプリが遅れている理由についてのあなたの質問に答えるべきです。 – murphguy

答えて

0

indexPaths.append(indexPath)cellForItemAtにあると思います。そのため、データをリロードした後でindexPathsが増加する理由を説明します。 NSArrayの代わりにNSSetを使用して、オブジェクトが一意であることを確認することができます。

これで、cell.invitee = invitees[indexPath.item]は、inviteeのdidSetを実装しましたか? これを実行した場合、まずバックグラウンドキューでデータを準備する必要があると思います。例えば。

DispatchQueue(label: "queue").async { 
    let image = <# process image here #> 
    let name = <# process name here #> 
    DispatchQueue.main.async { 
    self.imageView.image = image 
    self.label.text = name 
    } 
} 

私のヒントはあなたを助けることができます!

+0

私は 'invitee'に対してdidSetを実装しました。 NSSetはIndexPathとして設定する必要がありますか? 私はあなたを得ませんでした。 – Nizzam

+0

- あなたの 'didSet'はあなたのUI要素を満たすためにデータを処理するのに多くの時間がかかると思います。 - NSSetは、あなたのindexPathsが重複していないことを確認します! –

0

Collectionviewsは、iOSの中で最も強力なUIツールですが、誤って実行された場合や、誤って使用された場合(これは気にする必要はありません)、UXでは悪化する可能性があります。 。このようなことがどのように影響を受けているかを見るには、XCode Toolsを読み、UIパフォーマンスをデバッグするための使い方を読んでください。考慮すべき

重要な注意:

フレームごとの操作(すなわち、あなたのcollectionviewcellをロードし、拡張し、または拡張されていないが)スムーズスクロールのために実行するためにせいぜい17ミリ秒を取るべきではありません。

UICollectionView performance - _updateVisibleCellsNow

だから、可能な限りあなたの細胞が同じくらい簡単かつ効率的に行う必要があります。これは、特に展開可能なセル自体にcollectionviewsのような複雑なサブビューが含まれている場合には、これを開始するのに最適な場所です。

関連する問題