我目前有一个使用UICollectionView的UICollectionViewCompositionalLayout。当滚动/滚动停止时,我想在当前可见单元格中动画化一些视图。
不幸的是,似乎在某个部分将orthogonalScrollingBehavior设置为任何东西,但.none劫持了伴随着UIScrollView委托方法的UICollectionView。
想知道是否有任何当前的解决办法??获得分页行为和委托?。
设置布局
enum Section {
case main
}
override func awakeFromNib() {
super.awakeFromNib()
collectionView.collectionViewLayout = createLayout()
collectionView.delegate = self
}
func configure() {
snapshot.appendSections([.main])
snapshot.appendItems(Array(0..<10))
dataSource.apply(snapshot, animatingDifferences: false)
}
private func createLayout() -> UICollectionViewLayout {
let leadingItem = NSCollectionLayoutItem(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0))
)
leadingItem.contentInsets = .zero
let containerGroup = NSCollectionLayoutGroup.horizontal(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0)
),
subitems: [leadingItem])
let section = NSCollectionLayoutSection(group: containerGroup)
section.orthogonalScrollingBehavior = .groupPaging // WOULD LIKE PAGING & UISCROLLVIEW TO ALSO BE FIRED
let config = UICollectionViewCompositionalLayoutConfiguration()
config.scrollDirection = .horizontal
let layout = UICollectionViewCompositionalLayout(section: section, configuration: config)
return layout
}UICollectionViewDelegate
extension SlidingCardView: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
// THIS IS FIRED BUT UISCROLLVIEW METHODS NOT
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print(111)
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("1111111")
}
}发布于 2019-11-11 09:17:26
将orthogonalScrollingBehavior设置为节,嵌入处理区段中滚动的内部_UICollectionViewOrthogonalScrollerEmbeddedScrollView。此内部滚动视图作为子视图添加到集合视图中。
当您将自己设置为集合视图的delegate时,您应该接收滚动视图委托回调,但是只接收主集合视图的,它在节之间滚动,而不是在节中的项之间滚动。因为内部滚动视图(也可能是collectionViews,不确定)是完全不同的实例,并且您没有将自己设置为它们的委托,所以您没有收到它们的回调。
因此,据我所知,不应该有一种从内部滚动视图中接收这些回调的正式方法。
但是,如果你很好奇,并且你想尝试一下,你可以使用这个“黑”collectionView类:
import UIKit
final class OrtogonalScrollingCollectionView: UICollectionView {
override var delegate: UICollectionViewDelegate? {
get { super.delegate }
set {
super.delegate = newValue
subviews.forEach { (view) in
guard String(describing: type(of: view)) == "_UICollectionViewOrthogonalScrollerEmbeddedScrollView" else { return }
guard let scrollView = view as? UIScrollView else { return }
scrollView.delegate = newValue
}
}
}
}这将将您的委托设置为所有随正交部分而来的内部滚动视图。您不应该在生产环境中使用这种方法,因为不能保证苹果会以相同的方式保持集合视图的内部工作方式,这样这个黑客在将来可能无法工作,而且当您提交一个供发布的构建时,您可能会因为在UIKit中使用私有API而被拒绝。
发布于 2020-05-02 22:10:15
您可能只想使用visibleItemsInvalidationHandler回调您的NSCollectionLayoutSection,它的作用就像每次滚动该节时将调用的UIScrollViewDelegate一样。
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPagingCentered
section.visibleItemsInvalidationHandler = { (visibleItems, point, env) -> Void in
print(point)
}发布于 2021-03-11 16:35:01
在@Stoyan回答之后,我通过不寻找私有API,对类进行了很好的调整,使其与生产代码兼容。只需查看所有UIScrollView子类。
此外,我认为最好在集合重新加载期间更新委托,因为在设置委托时可能还没有完整的视图层次结构。
最后,该类现在递归地查找UIScrollView,因此不会遗漏任何东西。
final class OrthogonalScrollingCollectionView: UICollectionView {
override func reloadData() {
super.reloadData()
scrollViews(in: self).forEach { scrollView in
scrollView.delegate = delegate
}
}
override func reloadSections(_ sections: IndexSet) {
super.reloadSections(sections)
scrollViews(in: self).forEach { scrollView in
scrollView.delegate = delegate
}
}
fileprivate func scrollViews(in subview: UIView) -> [UIScrollView] {
var scrollViews: [UIScrollView] = []
subview.subviews.forEach { view in
if let scrollView = view as? UIScrollView {
scrollViews.append(scrollView)
} else {
scrollViews.append(contentsOf: self.scrollViews(in: view))
}
}
return scrollViews
}
}https://stackoverflow.com/questions/58791121
复制相似问题