gpt4 book ai didi

ios - UICollectionView 不会滚动到项目(在 : IndexPath, 处:位置)

转载 作者:行者123 更新时间:2023-12-01 19:38:38 25 4
gpt4 key购买 nike

我正在使用这种方法来滚动我的收藏 View 。

import UIKit
extension UICollectionView {
func scrollToLast() {
guard numberOfSections > 0 else {
print("number of sections < 0")
return
}
let lastSection = numberOfSections - 1
guard numberOfItems(inSection: lastSection) > 0 else {
print("number of items < 0")
return
}
let lastItemIndexPath = IndexPath(item: numberOfItems(inSection: lastSection) - 1,
section: lastSection)
self.scrollToItem(at: lastItemIndexPath, at: .centeredVertically, animated: true)
print("last Item (section, item #): \(lastItemIndexPath)")
}
}

在 View 加载并且 Collection View 中有项目之前,我不会调用此方法。在我向单元格原型(prototype)添加标签之前,它之前一直有效,现在虽然 View 看起来与新标签一样,但使用此方法不会滚动任何内容。我仍然可以手动 ScrollView 。注意:上述方法的输出正确地列出了调用该方法时最后一个 indexPath 处的最后一项。

我在控制台中有以下警告/错误,但它似乎与调用滚动时不一致,所以不确定它是否相关:

2019-11-04 06:01:13.017384-0800 AppName[17598:4494554] [CollectionView] An attempt to prepare a layout while a prepareLayout call was already in progress (i.e. reentrant call) has been ignored. Please file a bug. UICollectionView instance is (; layer = ; contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}; layout: ; dataSource: appBundle.instance



我如何称呼它的一个例子:(这是在 viewDidLoad 中)
DataService.instance.messageListener(roomId: room.id, { (result) in
self.messageArr.append(result)
self.messageArr = self.messageArr.sorted(by: { $0.date < $1.date})
self.collection.reloadData()
self.collection.scrollToLast()
self.messageTextArea.text = ""
})

编辑:我已经删除了对主队列的所有调用,并且行为已经改变。现在,当 messageListener 方法被触发时, View 将滚动到 Collection View 的顶部,但是当使用相同的 scrollToLast() 时方法在其他地方, View 滚动到最后一项应该 - 但只有在 View 手动滚动到底部之后。我也尝试将代码移至 viewDidAppear根据下面的答案,但没有效果。

最佳答案

这与您的问题无关,但我有一些建议:
1)调用self.scrollToItem之前不需要调用DispatchQueue.main.async,因为在DataService.instance.messageListener中已经切换到主线程。
2) messageArr 存在潜在的多线程问题,因为您从 DataService messageListener completionHandlers 线程中编辑了它(它可能在线程上)。据我了解 messageArr 是您的 Collection View 的数据源。因此,当您滚动 Collection View 或重新加载 Collection View 时,collectionView 将从主线程访问 messageArr。这将导致崩溃或未定义的行为,因为您从两个线程访问 messageArr 数组而没有锁定。解决方案之一是将整个 DataService.instance.messageListener 完成处理程序异步到主队列。

    DataService.instance.messageListener(roomId: room.id, { (result) in
DispatchQueue.main.async {
self.messageArr.append(result)
self.messageArr = self.messageArr.sorted(by: { $0.date < $1.date })
self.collection.reloadData()
self.collection.scrollToLast()
self.messageTextArea.text = ""
}
})

关于ios - UICollectionView 不会滚动到项目(在 : IndexPath, 处:位置),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58695078/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com