I have created a User Onboarding as a Collection View with 5 cells (pages).
The Collection View has a UIPageControl which shows an active page user currently on and 2 UIButtons (previous and next) which needed to manually scroll the pages if user don't want to swipe.
Here is how I manage the buttons IBAction when user tap:
@IBAction func prevButtonClicked(_ sender: UIButton) {
if currentPage != 0 {
currentPage -= 1
let indexPath = IndexPath(item: currentPage, section: 0)
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
}
@IBAction func nextButtonClicked(_ sender: UIButton) {
if currentPage == slides.count - 1 {
//hide onboarding
} else {
currentPage += 1
let indexPath = IndexPath(item: currentPage, section: 0)
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
}
Also if user swipes a page instead of tap on buttons I use scrollViewDidScroll() method to update UIPageControl dot:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleRectangle = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
let visiblePoint = CGPoint(x: visibleRectangle.midX, y: visibleRectangle.midY)
currentPage = collectionView.indexPathForItem(at: visiblePoint)?.row ?? 0
}
The currentPage is a computed property:
private var currentPage = 0 {
didSet {
pageControl.currentPage = currentPage
currentPage == 0 ? hidePreviousButton() : showPreviousButton()
}
}
I have a problem: when tap on buttons I force collectionView to scroll and update currentPage, therefore scrollViewDidScroll called and currentPage updates again.
Because of that when I tap on buttons I can see that UIPageControl dot and backButton are flicker since the code runs twice:
didSet {
pageControl.currentPage = currentPage
currentPage == 0 ? hidePreviousButton() : showPreviousButton()
}
Here is a GIF with the problem: https://cln.sh/ffXG9A
How can I avoid the double call to scrollViewDidScroll when tap on buttons?