首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设置UIScrollView委托方法时未调用UICollectionViewCompositionalLayout

设置UIScrollView委托方法时未调用UICollectionViewCompositionalLayout
EN

Stack Overflow用户
提问于 2019-11-10 17:21:30
回答 4查看 3.1K关注 0票数 7

我目前有一个使用UICollectionViewUICollectionViewCompositionalLayout。当滚动/滚动停止时,我想在当前可见单元格中动画化一些视图。

不幸的是,似乎在某个部分将orthogonalScrollingBehavior设置为任何东西,但.none劫持了伴随着UIScrollView委托方法的UICollectionView

想知道是否有任何当前的解决办法??获得分页行为和委托?

设置布局

代码语言:javascript
复制
  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

代码语言:javascript
复制
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")
  }
}
EN

回答 4

Stack Overflow用户

发布于 2019-11-11 09:17:26

orthogonalScrollingBehavior设置为节,嵌入处理区段中滚动的内部_UICollectionViewOrthogonalScrollerEmbeddedScrollView。此内部滚动视图作为子视图添加到集合视图中。

当您将自己设置为集合视图的delegate时,您应该接收滚动视图委托回调,但是只接收主集合视图的,它在节之间滚动,而不是在节中的项之间滚动。因为内部滚动视图(也可能是collectionViews,不确定)是完全不同的实例,并且您没有将自己设置为它们的委托,所以您没有收到它们的回调。

因此,据我所知,不应该有一种从内部滚动视图中接收这些回调的正式方法。

但是,如果你很好奇,并且你想尝试一下,你可以使用这个“黑”collectionView类:

代码语言:javascript
复制
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而被拒绝。

票数 8
EN

Stack Overflow用户

发布于 2020-05-02 22:10:15

您可能只想使用visibleItemsInvalidationHandler回调您的NSCollectionLayoutSection,它的作用就像每次滚动该节时将调用的UIScrollViewDelegate一样。

代码语言:javascript
复制
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPagingCentered

section.visibleItemsInvalidationHandler = { (visibleItems, point, env) -> Void in
   print(point)
}
票数 7
EN

Stack Overflow用户

发布于 2021-03-11 16:35:01

在@Stoyan回答之后,我通过不寻找私有API,对类进行了很好的调整,使其与生产代码兼容。只需查看所有UIScrollView子类。

此外,我认为最好在集合重新加载期间更新委托,因为在设置委托时可能还没有完整的视图层次结构。

最后,该类现在递归地查找UIScrollView,因此不会遗漏任何东西。

代码语言:javascript
复制
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
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58791121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档