设置UICollectionViewCompositionalLayout时未调用UIScrollView委托方法 据我所知,应该没有一种正式的方式来从内部滚动视图接收这些回调,这些内部滚动视图用于处理各部分中的滚动。

我目前有一个使用UICollectionView的{​​{1}}。我想在滚动/滚动停止时为当前可见单元格内的一些视图设置动画。

不幸的是,似乎在某个节上将UICollectionViewCompositionalLayout设置为除orthogonalScrollingBehavior以外的任何值,这劫持了.none附带的UICollectionView委托方法。

想知道目前是否有任何解决方法吗? 要获取分页行为和UIScrollView委托吗?

设置布局

UIScrollView

UICollectionViewDelegate

  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
  }
avagrace 回答:设置UICollectionViewCompositionalLayout时未调用UIScrollView委托方法 据我所知,应该没有一种正式的方式来从内部滚动视图接收这些回调,这些内部滚动视图用于处理各部分中的滚动。

您可能只想使用visibleItemsInvalidationHandler的{​​{1}}回调,就像NSCollectionLayoutSection的回调一样,每次该部分滚动时都会调用

UIScrollViewDelegate
,

orthogonalScrollingBehavior设置为一个节,将嵌入一个内部_UICollectionViewOrthogonalScrollerEmbeddedScrollView,用于处理节中的滚动。此内部滚动视图将作为子视图添加到您的集合视图。

当您将自己设为集合视图的delegate时,您应该收到主集合视图的滚动视图委托回调 BUT ONLY ,但该滚动在各部分之间而不是项目之间滚动在一节中。由于内部滚动视图(不确定,也可能是collectionView)是完全不同的实例,并且您没有将自己设置为它们的委托,因此您不会收到它们的回调。

据我所知,应该没有一种正式的方式来从内部滚动视图接收这些回调,这些内部滚动视图用于处理各部分中的滚动。

但是如果您好奇并想尝试一下,可以使用这个“ hacked” 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
            }
        }
    }
}

,这会将您的委托设置为正交部分随附的所有内部滚动视图。您不应该在生产环境中使用此功能,因为无法保证Apple会以相同的方式保持集合视图的内部工作方式,因此将来可能无法使用此hack,而且您可能会因在UIKit中使用私有API而被拒绝当您提交要发布的版本时。

,

在@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://www.f2er.com/3128291.html

大家都在问