Swift - UICollectionView reloadItems需要太长时间

时间:2021-07-10 21:21:27

I want to reload only single cell after user select the contact (method didSelect contact). If the number of item in cell getting bigger, the process is getting slower. I also try to implement in DispatchQueue.main.async { code } and it still take some time to load.

我想在用户选择联系人后重新加载单个单元格(方法didSelect contact)。如果单元格中的项目数量越来越大,则进程变慢。我也尝试在DispatchQueue.main.async {code}中实现它仍然需要一些时间来加载。

cellForItemAt and noOfItemInSection (AddCell) - Total cell 4

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 and noOfItemInSection (SubAddCell)

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])
            }
        }
    }

I have obtain the value of indexPaths at cellForItemAt method. If the invitee contains 5 items, the print(index) will print 19 values. I dont know why. Below is the image.

我在cellForItemAt方法中获取了indexPaths的值。如果被邀请者包含5个项目,则打印(索引)将打印19个值。我不知道为什么。下面是图像。

Swift  -  UICollectionView reloadItems需要太长时间

Design of the UI

UI的设计

Swift  -  UICollectionView reloadItems需要太长时间

How to optimize the reloadItems?

如何优化reloadItems?

Any help is really appreciated. Many thanks.

任何帮助都非常感谢。非常感谢。

2 个解决方案

#1


0  

I think you have this indexPaths.append(indexPath) in cellForItemAt so that why the indexPaths can increase after reload data. You might use NSSet instead of NSArray to make sure your objects are unique.

我认为你在cellForItemAt中有这个indexPaths.append(indexPath),以便在重载数据后indexPaths可以增加的原因。您可以使用NSSet而不是NSArray来确保您的对象是唯一的。

And with this: cell.invitee = invitees[indexPath.item], did you implement didSet for invitee? If you did, I think need to prepare data in background queue first. E.g.

有了这个:cell.invitee = invitees [indexPath.item],你为被邀请者实现了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
  }
}

Hope my tips could help you!

希望我的建议可以帮到你!

#2


0  

Collectionviews are the most powerful UI tool of iOS, but if done wrong, or if misused (which happens, don't worry), they can be worse for your UX. . To view how this stuff is affected read up on XCode Tools and how to use them to debug your UI performance.

Collectionviews是iOS中最强大的UI工具,但如果做错了,或者如果误用(发生了这种情况,请不要担心),对于你的用户体验来说,它们可能会更糟糕。 。要查看这些内容是如何受到影响的,请阅读XCode Tools以及如何使用它们来调试UI性能。

Important note to consider:

需要考虑的重要事项:

frame-by-frame operations (ie, loading your collectionviewcell, expanded, or unexpanded) should take no more than 17 ms to execute for smooth scrolling.

逐帧操作(即加载集合视图单元,展开或未展开)执行平滑滚动所需的时间不应超过17毫秒。

UICollectionView performance - _updateVisibleCellsNow

UICollectionView性能 - _updateVisibleCellsNow

So you need to make your cells as simple and efficient as possible. That's the best place to start, especially if your expandable cells themselves contain complex subviews like collectionviews.

所以你需要让你的细胞尽可能简单有效。这是最好的开始,特别是如果您的可扩展单元格本身包含像collectionviews这样的复杂子视图。

#1


0  

I think you have this indexPaths.append(indexPath) in cellForItemAt so that why the indexPaths can increase after reload data. You might use NSSet instead of NSArray to make sure your objects are unique.

我认为你在cellForItemAt中有这个indexPaths.append(indexPath),以便在重载数据后indexPaths可以增加的原因。您可以使用NSSet而不是NSArray来确保您的对象是唯一的。

And with this: cell.invitee = invitees[indexPath.item], did you implement didSet for invitee? If you did, I think need to prepare data in background queue first. E.g.

有了这个:cell.invitee = invitees [indexPath.item],你为被邀请者实现了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
  }
}

Hope my tips could help you!

希望我的建议可以帮到你!

#2


0  

Collectionviews are the most powerful UI tool of iOS, but if done wrong, or if misused (which happens, don't worry), they can be worse for your UX. . To view how this stuff is affected read up on XCode Tools and how to use them to debug your UI performance.

Collectionviews是iOS中最强大的UI工具,但如果做错了,或者如果误用(发生了这种情况,请不要担心),对于你的用户体验来说,它们可能会更糟糕。 。要查看这些内容是如何受到影响的,请阅读XCode Tools以及如何使用它们来调试UI性能。

Important note to consider:

需要考虑的重要事项:

frame-by-frame operations (ie, loading your collectionviewcell, expanded, or unexpanded) should take no more than 17 ms to execute for smooth scrolling.

逐帧操作(即加载集合视图单元,展开或未展开)执行平滑滚动所需的时间不应超过17毫秒。

UICollectionView performance - _updateVisibleCellsNow

UICollectionView性能 - _updateVisibleCellsNow

So you need to make your cells as simple and efficient as possible. That's the best place to start, especially if your expandable cells themselves contain complex subviews like collectionviews.

所以你需要让你的细胞尽可能简单有效。这是最好的开始,特别是如果您的可扩展单元格本身包含像collectionviews这样的复杂子视图。