Swift - UICollectionView reloadItems需要太长时间

时间:2017-10-25 03:52:57

标签: swift uicollectionview uicollectionviewcell nsindexpath

我想在用户选择联系人(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])
            }
        }
    }

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

enter image description here

UI的设计

enter image description here

如何优化reloadItems?

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

2 个答案:

答案 0 :(得分:0)

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

有了这个:cell.invitee = invitees[indexPath.item],你为invitee实现了didSet吗? 如果你这样做,我认为需要先在后台队列中准备数据。 E.g。

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

希望我的提示可以帮到你!

答案 1 :(得分:0)

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

需要考虑的重要注意事项:

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

UICollectionView performance - _updateVisibleCellsNow

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