Swift - UICollectionView reloadItems 需要太长时间
Posted
技术标签:
【中文标题】Swift - UICollectionView reloadItems 需要太长时间【英文标题】:Swift - UICollectionView reloadItems takes too long 【发布时间】:2017-10-25 03:52:56 【问题描述】:在用户选择联系人(method didSelect contact)
后,我只想重新加载单个单元格。如果单元格中的项目数越来越大,则该过程会变慢。我也尝试在DispatchQueue.main.async code
中实现,仍然需要一些时间来加载。
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])
我在cellForItemAt
方法中获得了indexPaths
的值。如果被邀请者包含 5 个项目,print(index)
将打印 19 个值。我不知道为什么。下面是图片。
用户界面设计
如何优化reloadItems?
非常感谢任何帮助。非常感谢。
【问题讨论】:
您能描述一下您的cellForItemAtIndexPath
方法的其余部分吗?您只显示您处理索引 1 处的单元格......而您显然使用了 19 个单元格。剩下的方法是什么?
@murphguy,它只有 4 个单元格。对于那个特定的单元格,里面有一个UICollectionView
。我已经更新了问题。
这就是你的挑战。可折叠单元格动画/处理相当繁重。所以这取决于:你是否在单元格内使用自动布局?单元格的内容是动态的吗?您是否通过单独的线程异步加载图像?这三个问题应该可以回答您的应用为何滞后的问题。
【参考方案1】:
我认为你在cellForItemAt
中有这个indexPaths.append(indexPath)
,所以为什么重新加载数据后 indexPaths 会增加。您可以使用 NSSet 而不是 NSArray 来确保您的对象是唯一的。
有了这个: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
希望我的建议能帮到你!
【讨论】:
我确实为invitee
实现了 didSet。 NSSet 需要设置为 IndexPath 吗?我没找到你。
-我猜您的didSet
需要花费大量时间来处理数据以填充到您的 UI 元素中。 - 并且 NSSet 确保你的 indexPaths 没有重复!【参考方案2】:
Collectionviews
是 ios 中最强大的 UI 工具,但如果做错了,或者如果被滥用(发生这种情况,不用担心),它们可能会对您的 UX 造成更糟的影响。 .要查看这些东西是如何受到影响的,请阅读 XCode 工具以及如何使用它们来调试您的 UI 性能。
需要考虑的重要提示:
逐帧操作(即加载您的collectionviewcell、展开或未展开)执行平滑滚动的时间不应超过17 毫秒。
UICollectionView performance - _updateVisibleCellsNow
因此,您需要使您的细胞尽可能简单和高效。这是最好的起点,尤其是当您的可扩展单元格本身包含复杂的子视图(如 collectionviews
)时。
【讨论】:
以上是关于Swift - UICollectionView reloadItems 需要太长时间的主要内容,如果未能解决你的问题,请参考以下文章
Swift:滚动时 UICollectionView 标题消失
swift UICollectionView + RxReachedBottom.swift
如何将 UIPageControl 连接到 UICollectionView (Swift)
Swift 4 UICollectionView 检测滚动结束