UICollectionViewCompositionalLayout с groupPagingCentered не начинается по центру - PullRequest
1 голос
/ 10 января 2020

Мой код макета очень прост, то, что вы видели в каждом руководстве или статье о новых композиционных макетах.

  func createLayout() -> UICollectionViewLayout {
    let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
    let item = NSCollectionLayoutItem(layoutSize: itemSize)
    item.contentInsets = .init(top: 0, leading: 5, bottom: 0, trailing: 5)

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

    let section = NSCollectionLayoutSection(group: group)
    section.orthogonalScrollingBehavior = .groupPagingCentered

    let layout = UICollectionViewCompositionalLayout(section: section)
    return layout
  }

Когда я запускаю приложение, ячейка не центрируется должным образом. Только когда я перетаскиваю ячейку на крошечное количество, она прыгает на правильное место.

До:

enter image description here

После того, как я перетащите его чуть-чуть:

enter image description here

Я не видел ни одного вопроса на SO об этой проблеме. Никто в Твиттере или в блогах не говорит об этом. Не уверен, что я тут не так делаю?

Ответы [ 4 ]

2 голосов
/ 10 января 2020

Это ожидаемое поведение. «По центру» означает, что ячейка привязывается к центру после прокрутки. Перед выполнением любой прокрутки вся группа прокручивается полностью вправо. Ваша группа имеет размер 0.93, поэтому разница незначительна. Эффект намного менее неприглядный, когда дробная ширина меньше.

0 голосов
/ 08 февраля 2020

Возможно, слишком поздно, но вот обходной путь:

func createLayout() -> UICollectionViewLayout {
    let layout = UICollectionViewCompositionalLayout { (sectionIndex, environment) -> NSCollectionLayoutSection? in
        let sideInset: CGFloat = 5

        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = .init(top: 0, leading: sideInset, bottom: 0, trailing: sideInset)

        let groupWidth = environment.container.contentSize.width * 0.93
        let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(groupWidth), heightDimension: .fractionalHeight(1.0))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])

        let section = NSCollectionLayoutSection(group: group)

        // add leading and trailing insets to the section so groups are aligned to the center
        let sectionSideInset = environment.container.contentSize.width - groupWidth - sideInset * 2
        section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: sectionSideInset, bottom: 0, trailing: sectionSideInset)

        // note this is not .groupPagingCentered
        section.orthogonalScrollingBehavior = .groupPaging

        return section
    }

    return layout
}
0 голосов
/ 20 января 2020

У меня работает с композиционным макетом:

override public func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    performInitialScroll()
}

private var isInitialScrollDone = false

private func performInitialScroll() {
    let hasElements = collectionView.dataSource?.collectionView(collectionView, numberOfItemsInSection: 0) ?? 0 > 0
    guard !isInitialScrollDone && hasElements else { return }
    isInitialScrollDone = true
    collectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: UICollectionView.ScrollPosition.centeredHorizontally, animated: false)
}

Начальный свиток невидим.

0 голосов
/ 13 января 2020

Вы можете попробовать это:

UPCarouselFlowLayout

Простота реализации и получения нужного вам результата.

Предположим, если я хочу показывать баннеры, используя вышеуказанную ссылку, вы можете получить результат.

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        DispatchQueue.main.async {
            let layout = self.collBannerView.collectionViewLayout as! UPCarouselFlowLayout
            layout.spacingMode = UPCarouselFlowLayoutSpacingMode.fixed(spacing: 10)
            //overlap(visibleOffset: 50)
            layout.itemSize = CGSize.init(width: self.view.frame.width - 70, height: 200)
            self.collBannerView.collectionViewLayout = layout
            let direction: UICollectionView.ScrollDirection = self.orientation.isPortrait ? .horizontal : .vertical
            layout.scrollDirection = direction
        }
    }
...