UICollectionView CompositionalLayout不调用UIScrollDelegate

问题描述 投票:1回答:1

这是我的问题:

1。 UICollectionView实现compositionalLayout后,不会调用ScrollViewDelegate。

使用flowLayout和UICollectionViewDataSource调用scrollView委托。一旦实现了diffable数据源和CompositionalLayout,scrollView委托将不再被调用。

2。在实现CompositionalLayout时,collectionView.decelerationRate = .fast被忽略

我的理解是,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的Apples示例代码,我发现了这种行为。

如果使用示例代码的网格布局

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个项目时,永远不会调用Scroll Delegate方法。

我仍然可以滚动,但是预期的行为应该是在我有垂直跳动时确实调用了滚动委托方法。

但是当有大约40个项目并且内容明显超出屏幕尺寸时,确实会调用滚动委托。

现在有趣的是加载我自己的布局时:

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通信的任何想法?

这是我的问题:1.一旦UICollectionView实现compositionalLayout,就不会调用ScrollViewDelegate。使用flowLayout和UICollectionViewDataSource时,scrollView委托得到...

swift uicollectionview uiscrollview
1个回答
0
投票

似乎是UICollectionView组成布局中水平滚动组的意外行为

© www.soinside.com 2019 - 2024. All rights reserved.