0

尝试实现 IGListKit 库时,我遇到了我的单元格被不必要地更新的问题。我正在使用adapter.dataSource表中每行一个部分的单例。

最小示例:

import IGListKit

class ContentItem: ListDiffable {
  weak var item: Content?
  weak var section: ContentSectionController?

  func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
    return true
  }

  init(item: Content?) {
    self.item = item
  }
}

class ContentSectionController: ListSectionController {
  weak var object: ContentItem?
  override func didUpdate(to object: Any) {
    self.object = object as? ContentItem
    self.object?.section = self
    // should only be called on updates
  }

  override func sizeForItem(at index: Int) -> CGSize {
    guard let content = object?.item else {
      return CGSize(width: 0, height: 0)
    }
    // calculate height
  }

  override func cellForItem(at index: Int) -> UICollectionViewCell {
    let cell = collectionContext!.dequeueReusableCellFromStoryboard(withIdentifier: "ContentCell", for: self, at: index)

    (cell as? ContentCell)?.item = object // didSet will update cell
    return cell
  }

  override init() {
    super.init()
    self.workingRangeDelegate = self
  }
}

extension ContentSectionController: ListWorkingRangeDelegate {
  func listAdapter(_ listAdapter: ListAdapter, sectionControllerWillEnterWorkingRange sectionController: ListSectionController) {
    // prepare
  }

  func listAdapter(_ listAdapter: ListAdapter, sectionControllerDidExitWorkingRange sectionController: ListSectionController) {
    return
  }
}

class ContentDataSource: NSObject {
  static let sharedInstance = ContentDataSource()

  var items: [ContentItem] {
    return Content.displayItems.map { ContentItem(item: $0) }
  }
}

extension ContentDataSource: ListAdapterDataSource {
  func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
    return items
  }

  func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
    return ContentSectionController()
  }

  func emptyView(for listAdapter: ListAdapter) -> UIView? {
    return nil
  }
}

/// VC ///

class ContentViewController: UIViewController {
  @IBOutlet weak var collectionView: UICollectionView!

  override func viewDidLoad() {
    super.viewDidLoad()

    let updater = ListAdapterUpdater()
    adapter = ListAdapter(updater: updater, viewController: self, workingRangeSize: 2)
    adapter.collectionView = collectionView
    adapter.dataSource = ContentDataSource.sharedInstance
  }
  var adapter: ListAdapter!
  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    adapter.performUpdates(animated: true)
  }
  // ...
}

在我调用的每个视图上出现adapter.performUpdates(animated: true),它不应该更新单元格,因为isEqual它被覆盖了true。尽管如此,所有细胞didUpdate都被触发,再次调用cellForItem

4

1 回答 1

1

IGListKit 需要diffIdentifierisEqual使用 IGListDiffable 协议来实现,以便比较两个对象的身份/相等性。(您的模型中缺少差异标识符)。

我的理解是,在后台,ListKit 检查对象的两个差异标识符是否相等,如果它们相等,则继续将它们与isEqual.

资源: IGListKit 最佳实践 IGListDiffable 协议参考

于 2021-03-10T01:13:58.140 回答