问题描述
我正在使用一个复杂的TableViewCell,该表内部有一个CollectionView和一个StackView。此单元格可以在StackView中具有多个子视图(大约100个视图),具体取决于选择了多少ColectionViewCell。问题是当在表格上滚动时,当下一个单元格出队时,它会滞后。我认为主要原因是因为它要从堆栈中删除所有子视图,然后再次添加它们。
class MainViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return presenter?.numberOfSections ?? 0
}
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return presenter?.numberOfJobs(in: section) ?? 0
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: SelectionCell = tableView.dequeueReusableCell(for: indexPath)
if let activity = presenter?.activity(at: indexPath),let name = presenter?.name(at: indexPath) {
cell.configure(activity: activity,value: presenter?.rate(at: indexPath),name: name,infos: presenter?.InfosDesc(at: indexPath) ?? [],selectedRowIndices: presenter?.selectedRowIndices(at: indexPath) ?? [],offset: offsetsForIndexPaths[indexPath],delegate: self,row: indexPath.row)
}
cell.didSelectRowHandler = { [weak self] rowIndex in
self?.presenter?.didSelectRow(activityIndexPath: indexPath,rowIndex: rowIndex)
if let indexPathsToReload = tableView.indexPathsForVisibleRows {
tableView.reloadRows(at: indexPathsToReload,animated: false)
}
}
cell.didSelectAllHandler = { [weak self] in
self?.presenter?.didSelectAllRows(activityIndexPath: indexPath)
if let indexPathsToReload = tableView.indexPathsForVisibleRows {
tableView.reloadRows(at: indexPathsToReload,animated: false)
}
}
cell.diddeselectAllHandler = { [weak self] in
self?.presenter?.diddeselectAllRows(activityIndexPath: indexPath)
if let indexPathsToReload = tableView.indexPathsForVisibleRows {
tableView.reloadRows(at: indexPathsToReload,animated: false)
}
}
cell.diddeselectRowHandler = { [weak self] rowIndex in
self?.presenter?.diddeselectRow(activityIndexPath: indexPath,animated: false)
}
}
cell.didInputNumberForRow = { [weak self] number,rowNumber in
self?.presenter?.didInputNumber(activityIndexPath: indexPath,value: number,for: rowNumber)
}
cell.didScrollHandler = { [weak self] offset in
self?.offsetsForIndexPaths[indexPath] = offset
}
cell.didChangeValue = { [weak self] newValue in
self?.presenter?.didChangeValue(newValue,activityIndexPath: indexPath)
}
return cell
}
}
class SelectionCell: UITableViewCell {
var didSelectRowHandler: ((Int) -> Void)?
var didChangeValue: ((Double) -> Void)?
var didInputNumberForRow: ((Int,Int) -> Void)?
var diddeselectRowHandler: ((Int) -> Void)?
var didScrollHandler: ((CGPoint) -> Void)?
var didSelectAllHandler: (() -> Void)?
var diddeselectAllHandler: (() -> Void)?
... other properties ...
private lazy var inputField: CustomInputField = { ... }
private lazy var numberFields = UIStackView.vertical(spacing: 10)
private lazy var collectionView: UICollectionView = { … }
override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil
numberFields.subviews.forEach { $0.removeFromSuperview() }
activityLabel.attributedText = nil
otherLabel.isHidden = true
inputField.value = nil
}
func configure<Delegate: UICollectionViewDataSource>( activity: Activity,value: Double?,name: String,infos: [(Info,NSAttributedString)],selectedRowIndices: [Int],offset: CGPoint?,delegate: Delegate,row: Int) {
if activity.type.typeName?.caseInsensitiveCompare(activity.type.name) != .orderedSame {
activityTypeLabel.attributedText = NSAttributedString(string: activity.type.name,attributes: .treeNumberInfoText)
}
InputField.value = value
nameLabel.attributedText = NSAttributedString(string: name,attributes: .treeNumberInfoText)
let image = GraphicHelper.createImage(withInitials: name.nameInitials,backgroundColor: .random(seed: name,maxBrightness: 0.7),attributes: .initials,diameter: 50)
userImageView.image = image
{ ... more cell configuration ... }
infos.forEach { info,desc in
let infoInputField = InfoInputDescriptionView(info: info,description: desc,delegate: self)
infoInputField.addArrangedSubview(infoInputField)
}
collectionView.dataSource = delegate
collectionView.tag = row
collectionView.reloadData()
dispatchQueue.main.async {
self.collectionView.performBatchUpdates(nil) { _ in
selectedRowIndices.forEach { rowIndex in
let path = IndexPath(row: rowIndex,section: 0)
if self.collectionView.isIndexPathValid(path) {
self.collectionView.selectItem(at: path,animated: false,scrollPosition: .centeredHorizontally)
}
}
if let offset = offset {
self.collectionView.setContentOffset(offset,animated: false)
}
}
}
didSelectAll = selectedRowIndices.count == collectionView.numberOfItems(inSection: 0)
}
extension SelectionCell: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView,didSelectItemAt indexPath: IndexPath) {
didSelectRowHandler?(indexPath.row)
}
func collectionView(_ collectionView: UICollectionView,diddeselectItemAt indexPath: IndexPath) {
diddeselectRowHandler?(indexPath.row)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
didScrollHandler?(scrollView.contentOffset)
}
}
我尝试重用StackCells而不是全部删除它们,但是每次都要重新配置StackViews很复杂(无法解决滞后问题),同时下一个TableCell可能具有或未选择值,因此堆栈可能是空的。此时,我正在考虑将TableView替换为StackView,还有其他建议吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)