How to set UIPageControl currentPage state same for both collectionView and next/prev buttons?

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

我的水平 collectionView 中有 5 张图像,它看起来像旋转木马,一个单元格与其他单元格重叠。另外,我有一个 UIPageControl 和下一个/上一个按钮,用于更改轮播项目。

class ViewController:
UIViewController,
UICollectionViewDelegate,
UICollectionViewDataSource {

@IBOutlet private var collectionView: UICollectionView!
@IBOutlet private var nextButton: UIButton!
@IBOutlet private var previousButton: UIButton!
@IBOutlet private var pageControl: UIPageControl!

let images: [UIImage] = [
    image1,
    image2,
    image3,
    image4,
    image5,
]

var currentPage: Int = 0 {
    didSet {
        pageControl.currentPage = currentPage
    }
}

在 viewDidLoad 方法中,我将 pageControl 项目设置为:

 override func viewDidLoad() { 
    collectionView.delegate = self
    collectionView.dataSource = self
    previousButton.isHidden = true
    nextButton.isEnabled = true

    pageControl.numberOfPages = images.count
    pageControl.currentPage = 0
    pageControl.clipsToBounds = false
}

在使用下一个/上一个按钮在 collectionView 中显示轮播项目时效果很好。但问题是 currentPage 状态没有为 scrollViewDidEndDecelerating 方法更新,并且在使用下一个/上一个按钮进行一些遍历后,它会自动滚动到 collectionView 的第一个单元格或最后一个单元格,并且 currentPage 状态令人困惑。

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    let pageNumber = ceil(scrollView.contentOffset.x / scrollView.frame.size.width)
    pageControl.currentPage = Int(pageNumber)
    currentPage = Int(pageNumber)
    updateButtonStates(with: currentPage)
    updateUI(with: currentPage)
}

@IBAction func didTapOnPreviousButton(_ sender: Any) {
    if currentPage > 0 {
        currentPage -= 1
        print("IndexPath(item: currentPage, section: 0)", IndexPath(item: currentPage, section: 0))
        collectionView?.isPagingEnabled = false
        collectionView.scrollToItem(
            at: IndexPath(item: currentPage,
                          section: 0),
            at: .centeredHorizontally,
            animated: true)
        collectionView?.isPagingEnabled = true
        pageControl.currentPage = currentPage
        updateButtonStates(with: currentPage)
        updateUI(with: currentPage)
    }
}

@IBAction func didTapNextButton(_ sender: Any) {
    if currentPage < images.count - 1 {
        currentPage += 1
        print("IndexPath(item: currentPage, section: 0)", IndexPath(item: currentPage, section: 0))
        collectionView?.isPagingEnabled = false
        collectionView.scrollToItem(
            at: IndexPath(item: currentPage,
                          section: 0),
            at: .centeredHorizontally,
            animated: true)
        collectionView?.isPagingEnabled = true
        pageControl.currentPage = currentPage
        updateButtonStates(with: currentPage)
        updateUI(with: currentPage)
    }
}

private func updateUI(with currentPage: Int) {
    pageControl.currentPage = currentPage
    previousButton.isHidden = currentPage == 0
    nextButton.isHidden = currentPage == images.count - 1
}

func updateButtonStates(with currentPage: Int) {
    pageControl.currentPage = currentPage
    previousButton.isEnabled = currentPage > 0
    nextButton.isEnabled = currentPage < images.count
}

我想要做的是当用户在单元格之间滚动然后单击下一个/上一个按钮时,pageControl 状态对于两个不同的操作应该相同。

ios swift uicollectionview uipagecontrol
1个回答
0
投票

这就是我解决问题的方法:

我使用 scrollViewWillEndDragging 方法来获取 scrollView 的精确点和 collectionView 的当前 itemWidth。

func scrollViewWillEndDragging(
    _: UIScrollView,
    withVelocity _: CGPoint,
    targetContentOffset: UnsafeMutablePointer<CGPoint>
) {
    let offset = targetContentOffset.pointee.x
    let widthPerItem = collectionView.bounds.width / images.count
    pageControl.currentPage = Int(floor(offset / widthPerItem))
    updateButtonStates(with: pageControl.currentPage)
    updateUI(with: pageControl.currentPage)
}

还使用 IBAction 更新更新了 UI 和下一个/上一个按钮状态:

 @IBAction
 func didTapOnPreviousButton(_: Any) {
        let prevIndex = max(pageControl.currentPage - 1, 0)
        let indexPath = IndexPath(item: prevIndex, section: 0)
        pageControl.currentPage = prevIndex
        collectionView?.isPagingEnabled = false
        collectionView.scrollToItem(
            at: indexPath,
            at: .centeredHorizontally,
            animated: true
        )
        updateButtonStates(with: pageControl.currentPage)
        updateUI(with: pageControl.currentPage)
    }

 @IBAction
 func didTapOnNextButton(_: Any) {
        let nextIndex = min(pageControl.currentPage + 1, images.count - 1)
        let indexPath = IndexPath(item: nextIndex, section: 0)
        pageControl.currentPage = nextIndex
        collectionView?.isPagingEnabled = false
        collectionView.scrollToItem(
            at: indexPath,
            at: .centeredHorizontally,
            animated: true
        )
        updateButtonStates(with: pageControl.currentPage)
        updateUI(with: pageControl.currentPage)
    }

简而言之,

pageControl.currentPage
状态应该在相应的方法中更新,例如下一个/上一个按钮操作和滚动视图。

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