Has*_*h88 4 objective-c ios uicollectionview
我有一个水平UICollectionView的几个部分,每个部分包含几个单元格,如下所示:
第 0 部分:取消选择的一个单元格。
第 1 部分:最近选择的项目。
第 2 部分及以后:每个部分都有几个可以选择的项目。
When a cell from section 2 or later is selected, a copy of that item is inserted to the start section 1 in the data source, and I want to reload section 1 to reflect the updated recent items. 但是,我想保留滚动位置。我试过了:
[collectionView reloadSections:setWithIndex1]和
[collectionView reloadItemsAtIndexPaths:arrayWithAllSection1IndexPaths]
我已经尝试使用[collectionView performBatchUpdates:],但是我尝试过的所有操作都使滚动偏移量重置为集合视图的开头。我已经尝试通过使用基本集合视图启动一个新应用程序并使用 重新加载一个部分来进行完整性检查reloadSections,并且它具有不重置滚动偏移的期望行为。但是在我现有的代码库中做同样的事情确实会重置偏移量。
我已经倾注了我的collectionView相关代码来寻找reloadData's、setContentOffsets's 和类似的东西,但对于我的生活,我找不到导致它的原因。有什么我遗漏的东西可以在更新后重置滚动位置吗?
如果您可以在没有任何动画的情况下执行此操作,我将执行以下操作:
UIView.setAnimationsEnabled(false)
Run Code Online (Sandbox Code Playgroud)
let selectedCell = collectionView.cellForItem(at: indexPath)
let visibleRect = collectionView.convert(collectionView.bounds, to: selectedCell)
Run Code Online (Sandbox Code Playgroud)
selectedObjects.insert(allObjects[indexPath.item], at: 0)
collectionView.performBatchUpdates({
// INSERTING NEW ITEM
let indexPathForNewItem = IndexPath(item: 0, section: 1)
collectionView.insertItems(at: [indexPathForNewItem])
}) { (finished) in
// GETTING NEW VISIBLE RECT FOR SELECTED CELL
let updatedVisibleRect = collectionView.convert(collectionView.bounds, to: selectedCell)
// UPDATING COLLECTION VIEW CONTENT OFFSET
var contentOffset = collectionView.contentOffset
contentOffset.x = contentOffset.x + (visibleRect.origin.x - updatedVisibleRect.origin.x)
collectionView.contentOffset = contentOffset
}
Run Code Online (Sandbox Code Playgroud)
UIView.setAnimationsEnabled(true)
Run Code Online (Sandbox Code Playgroud)
我在根据您描述的行为调整的简单集合视图上进行了尝试。这是整个实现(collecionView 在故事板中,所以如果你想测试我的解决方案,不要忘记连接插座。)
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
let reuseIdentifier = "cell.reuseIdentifier"
var allObjects: [UIColor] = [.red, .yellow, .orange, .purple, .blue]
var selectedObjects: [UIColor] = []
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView.delegate = self
self.collectionView.dataSource = self
self.collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: self.reuseIdentifier)
}
}
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
switch section {
case 0: return 1
case 1: return selectedObjects.count
case 2: return allObjects.count
default: return 0
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseIdentifier, for: indexPath)
switch indexPath.section {
case 0: cell.contentView.backgroundColor = .black
case 1: cell.contentView.backgroundColor = selectedObjects[indexPath.item]
case 2: cell.contentView.backgroundColor = allObjects[indexPath.item]
default: break
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 150, height: collectionView.frame.size.height)
}
}
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: false)
switch indexPath.section {
case 0:
self.selectedObjects.removeAll()
collectionView.reloadData()
case 2:
if selectedObjects.contains(allObjects[indexPath.item]) {
break
} else {
// SOLUTION //
UIView.setAnimationsEnabled(false)
let selectedCell = collectionView.cellForItem(at: indexPath)
let visibleRect = collectionView.convert(collectionView.bounds, to: selectedCell)
selectedObjects.insert(allObjects[indexPath.item], at: 0)
collectionView.performBatchUpdates({
let indexPathForNewItem = IndexPath(item: 0, section: 1)
collectionView.insertItems(at: [indexPathForNewItem])
}) { (finished) in
let updatedVisibleRect = collectionView.convert(collectionView.bounds, to: selectedCell)
var contentOffset = collectionView.contentOffset
contentOffset.x = contentOffset.x + (visibleRect.origin.x - updatedVisibleRect.origin.x)
collectionView.contentOffset = contentOffset
}
UIView.setAnimationsEnabled(true)
// END OF SOLUTION //
}
default:
break
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
我也试过更换
let indexPathForNewItem = IndexPath(item: 0, section: 1)
collectionView.insertItems(at: [indexPathForNewItem])
Run Code Online (Sandbox Code Playgroud)
和
collectionView.reloadSections(IndexSet(integer: 1))
Run Code Online (Sandbox Code Playgroud)
它也工作得很好,没有任何闪烁,所以这取决于你,哪个对你更方便。
| 归档时间: |
|
| 查看次数: |
7235 次 |
| 最近记录: |