简体   繁体   English

UICollectionView 水平分页旋转后不居中

[英]UICollectionView horizontal paging not centring after rotation

I am currently working on a horizontal gallery scroll view.我目前正在研究水平画廊滚动视图。 I have decided to use UICollectionView with horizontal paging enabled.我决定使用启用水平分页的 UICollectionView。 It almost works great... expect on rotation the collection view cells are not centred (see screenshot attached), where red is the first cell and yellow is the second one.它几乎可以很好地工作...期望在旋转时集合视图单元格不居中(请参见随附的屏幕截图),其中红色是第一个单元格,黄色是第二个单元格。

在此处输入图像描述

It usually works fine on the first rotation but then just messes up:D它通常在第一次旋转时工作正常,但随后就搞砸了:D

This is the code I have for setting up the class:这是我用于设置 class 的代码:

class GalleryScrollView: UIView {
    private var collectionView: UICollectionView!
    private var layout: UICollectionViewFlowLayout!
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupView()
    }

    override func layoutSubviews() {
        layout.invalidateLayout()
    }

    private func setupView() {
        layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        collectionView = UICollectionView(frame: self.frame,
                                          collectionViewLayout: layout)
        collectionView.register(UINib(nibName: "PhotoGalleryCell", bundle: nil), forCellWithReuseIdentifier: "photoGalleryCell")
        collectionView.isPagingEnabled = true
        collectionView.contentInsetAdjustmentBehavior = .never
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.autoresizingMask = .flexibleWidth
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .green
        self.addSubview(collectionView)

        NSLayoutConstraint.activate([
            collectionView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            collectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
            collectionView.topAnchor.constraint(equalTo: self.topAnchor),
            collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
        ])

        collectionView.reloadData()
    }
}

Followed by the collection view setup:其次是集合视图设置:

extension GalleryScrollView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoGalleryCell", for: indexPath) as? PhotoGalleryCell else {
        return UICollectionViewCell()
    }

    if indexPath.item == 0 {
        cell.backgroundColor = .red
    } else {
        cell.backgroundColor = .yellow
    }

    return cell
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    2
}

func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize {
    return self.frame.size
}

I tried playing around with func collectionView(_ collectionView: UICollectionView, targetContentOffsetForProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { but for some reason the func was never called.我尝试使用func collectionView(_ collectionView: UICollectionView, targetContentOffsetForProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint {但由于某种原因从未调用过 func。

Did anyone else run into this problem?有没有其他人遇到过这个问题? I saw a lot of topics in objective c threads, not much in swift.我在目标 c 线程中看到了很多主题,在 swift 中看到的主题不多。 I am also somewhat struggling to understand why this is happening, so just understanding the problem would be very helpful.我也有点难以理解为什么会发生这种情况,所以仅仅理解这个问题会非常有帮助。 Thank you!谢谢!

You don't seem to have handled rotations.你似乎没有处理旋转。 You need to reloadData when a rotation occurs.发生旋转时需要重新reloadData You'll get the event in UIViewController from there you can call reloadData on the instance of your UICollectionView .您将在UIViewController中获得该事件,您可以在UICollectionView的实例上调用reloadData

class GalleryViewController: UIViewController {
    //...
    var galleryScrollView: GalleryScrollView
    //...
    override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
        super.willTransition(to: newCollection, with: coordinator)
        galleryScrollView.collectionViewLayout.invalidateLayout()
    }
    //...
}

Then in GalleryScrollView :然后在GalleryScrollView

class GalleryScrollView: UIView {
    var currentVisibleIndexPath = IndexPath(row: 0, section: 0)
    //....
}

extension GalleryScrollView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    //...
    func collectionView(_ collectionView: UICollectionView, targetContentOffsetForProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint {
        let attributes =  collectionView.layoutAttributesForItem(at: currentVisibleIndexPath)
        let newOriginForOldIndex = attributes?.frame.origin
        return newOriginForOldIndex ?? proposedContentOffset
    }

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

        let center = CGPoint(x: scrollView.contentOffset.x + (scrollView.frame.width / 2), y: (scrollView.frame.height / 2))
        if let indexPath = self.screenView.indexPathForItem(at: center) {
            currentVisibleIndexPath = indexPath
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM