gpt4 book ai didi

swift - UICollectionView CompositionalLayout 不调用 UIScrollDelegate

转载 作者:行者123 更新时间:2023-12-03 09:18:50 24 4
gpt4 key购买 nike

这是我的问题:
1. ScrollViewDelegate 没有被调用 一旦 UICollectionView 实现了 compositionalLayout。
使用 flowLayout 和 UICollectionViewDataSource 调用 scrollView 委托(delegate)。一旦我实现了 diffable 数据源和 CompositionalLayout,就不会再调用 scrollView 委托(delegate)了。
2. collectionView.decelerationRate = .fast 被忽略 实现 CompositionalLayout 时
我的理解是 UICollectionViewDelegate 应该调用 UIScrollViewDelegate,我已经看得很远但没有运气。有人可以指出我错过了什么吗?我整合compositionalLayout错了吗?
这是我的代码:



import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UIScrollViewDelegate {

enum Section {
case weekdayHeader
}

@IBOutlet weak var collectionView: UICollectionView!

let weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday","Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

var weekdaysArr = [Weekdays]()

var dataSource: UICollectionViewDiffableDataSource<Section, Weekdays>! = nil

private let cellReuseIdentifier = "myCell"



override func viewDidLoad() {
super.viewDidLoad()
self.collectionView.delegate = self
self.collectionView.register(UINib(nibName: "MyCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: cellReuseIdentifier)
self.collectionView.decelerationRate = .normal

configureCollectionView()
configureDataSource()
configureWeekdays()
updateCollectionView()

// Do any additional setup after loading the view.
}

func configureCollectionView(){
self.collectionView.delegate = self
self.collectionView.collectionViewLayout = generateLayout()
}

func generateLayout() -> UICollectionViewLayout {

let itemSize = NSCollectionLayoutSize(
widthDimension: .estimated(10),
heightDimension: .fractionalHeight(1))
let weekdayItem = NSCollectionLayoutItem(layoutSize: itemSize)
// weekdayItem.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 50, bottom: 5, trailing: 50)

let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(0.3),
heightDimension: .fractionalHeight(1.0))
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [weekdayItem])

// let spacing = CGFloat(10)
// group.interItemSpacing = .fixed(spacing)

let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = CGFloat(20)
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 500)
section.orthogonalScrollingBehavior = .continuousGroupLeadingBoundary




let layout = UICollectionViewCompositionalLayout(section: section)

return layout

}

func configureDataSource() {
dataSource = UICollectionViewDiffableDataSource
<Section, Weekdays>(collectionView: collectionView)
{ (collectionView: UICollectionView, indexPath: IndexPath, weekday: Weekdays) -> UICollectionViewCell? in
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cellReuseIdentifier, for: indexPath) as? MyCollectionViewCell else {
fatalError("Cannot create a new cell") }
cell.titleLabel.text = weekday.name
print("weekday.name = \(weekday.name)")
return cell
}
// let snapshot = snapshotForCurrentState()
// dataSource.apply(snapshot, animatingDifferences: false)
}

func configureWeekdays(){

weekdaysArr.append(Weekdays(name: "Monday"))
weekdaysArr.append(Weekdays(name: "Tuesday"))
weekdaysArr.append(Weekdays(name: "Wednesday"))
weekdaysArr.append(Weekdays(name: "Thursday"))
weekdaysArr.append(Weekdays(name: "Friday"))
weekdaysArr.append(Weekdays(name: "Saturday"))
weekdaysArr.append(Weekdays(name: "Sunday"))

}

func updateCollectionView(){
var snapshot = NSDiffableDataSourceSnapshot<Section, Weekdays>()
snapshot.appendSections([.weekdayHeader])
snapshot.appendItems(weekdaysArr, toSection: .weekdayHeader)
dataSource.apply(snapshot, animatingDifferences: false)
}



//MARK: Scroll View Delegate

func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("ScrollView decel rate: \(scrollView.decelerationRate)")
}

public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("Begin")
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("End")
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
print("END")
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

print("Did select a cell here")

}


}

struct Weekdays: Hashable {
let identifier: UUID = UUID()
let name: String

func hash(into hasher: inout Hasher){
return hasher.combine(identifier)
}

static func == (lhs: Weekdays, rhs: Weekdays) -> Bool {
return lhs.identifier == rhs.identifier
}
}


谢谢
编辑:更新的代码 -
编辑:与来自 WWDC 的 Apple 示例代码进行比较,我发现了这种行为。
如果我使用示例代码网格布局
func gridLayout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.2),
heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)

let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(0.2))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
subitems: [item])

let section = NSCollectionLayoutSection(group: group)

let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
当只有 7 个项目时,滚动委托(delegate)方法永远不会被调用。
我仍然可以滚动,并且预期的行为应该是滚动委托(delegate)方法确实被调用,因为我有垂直反弹。
当有大约 40 个项目并且内容显然超出屏幕大小时,滚动委托(delegate)确实会被调用。
现在有趣的是,在加载我自己的布局时:
func generateLayout() -> UICollectionViewLayout {

let itemSize = NSCollectionLayoutSize(
widthDimension: .estimated(10),
heightDimension: .fractionalHeight(1))
let weekdayItem = NSCollectionLayoutItem(layoutSize: itemSize)
// weekdayItem.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 50, bottom: 5, trailing: 50)

let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(0.3),
heightDimension: .fractionalHeight(1.0))
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [weekdayItem])

// let spacing = CGFloat(10)
// group.interItemSpacing = .fixed(spacing)

let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = CGFloat(20)
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 500)
section.orthogonalScrollingBehavior = .continuousGroupLeadingBoundary




let layout = UICollectionViewCompositionalLayout(section: section)

return layout

}
滚动代表永远不会被调用。即使有 40 多个项目。
关于如何强制 UICollectionView 与其 ScrollViewDelegates 进行通信的任何想法?

最佳答案

答案是使用 visibleItemsInvalidationHandler 关闭 部分(NSCollectionLayoutSection)。
每当事件导致动画时,此处理程序都会接收更新。它的操作类似于 scrollViewDidScroll在水平滚动组上,它将传递所有项目、 ScrollView 偏移量和 NSCollectionLayoutEnvironment。
https://developer.apple.com/documentation/uikit/nscollectionlayoutsection/3199096-visibleitemsinvalidationhandler
例子:

section.visibleItemsInvalidationHandler = { [weak self] visibleItems, point, environment in
self?.currentIndex = visibleItems.last?.indexPath.row
}

关于swift - UICollectionView CompositionalLayout 不调用 UIScrollDelegate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59674538/

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