JamesG
JamesG

Reputation: 1601

Swift: Updating UIPageControl from ScrollView

I seem to be having some issues getting the UIPageControl to work.

I have a ViewController that holds a ScrollView. This ScrollView loads nib files that can be swiped. See image:

enter image description here

Here is the code that loads these:

self.addChildViewController(vc0)
self.displayReportView.addSubview(vc0.view)
vc0.didMoveToParentViewController(self)
        
var frame1 = vc1.view.frame
frame1.origin.x = self.view.frame.size.width
vc1.view.frame = frame1
self.addChildViewController(vc1)
self.displayReportView.addSubview(vc1.view)
vc1.didMoveToParentViewController(self)

// And so on
...

This works fine as in they scroll correctly etc..

Now, on the ViewController (one holding the scrollview) I added the delegate:

UIScrollViewDelegate

created some variables:

 var frame: CGRect = CGRectMake(0, 0, 0, 0)
 var colors:[UIColor] = [UIColor.redColor(), UIColor.blueColor(), UIColor.greenColor(), UIColor.yellowColor()]
 var pageControl : UIPageControl = UIPageControl(frame: CGRectMake(50, 300, 200, 20))

I added some functions that are needed:

func configurePageControl() {
    // The total number of pages that are available is based on how many available colors we have.
    
    self.pageControl.numberOfPages = 4
    self.pageControl.currentPage = 0
    self.pageControl.tintColor = UIColor.redColor()
    self.pageControl.pageIndicatorTintColor = UIColor.blackColor()
    self.pageControl.currentPageIndicatorTintColor = UIColor.greenColor()
    self.view.addSubview(pageControl)
    
}


// MARK : TO CHANGE WHILE CLICKING ON PAGE CONTROL
func changePage(sender: AnyObject) -> () {
    let x = CGFloat(pageControl.currentPage) * displayReportView.frame.size.width
    displayReportView.setContentOffset(CGPointMake(x, 0), animated: true)
}


func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    
    let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
    pageControl.currentPage = Int(pageNumber)
}

Now, When I run the app the scrollview dots show, but when I swipe they do not update.

Question

How do I update the dots to reflect what view is showing?

let me know if you need anything else from my code to see functionality.

Upvotes: 2

Views: 8512

Answers (2)

matt
matt

Reputation: 534885

You can certainly do what you're describing, if you have a paging scroll view; I have an example of it that uses this code:

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    let x = scrollView.contentOffset.x
    let w = scrollView.bounds.size.width
    pageControl.currentPage = Int(x/w)
}

Except for your round, that looks a lot your code, which makes me think that your code should work. That makes me think that something else is just misconfigured. Is this a paging scroll view? Did you remember to make this object your scroll view's delegate? Use logging or a breakpoint to be certain that your scrollViewDidEndDecelerating is even being called in the first place.

However, I would just like to point out that the configuration you are describing is effectively what UIPageViewController gives you for free — a scroll view with view controller views, plus a page control — so you might want to use that instead.

Upvotes: 8

TotoroTotoro
TotoroTotoro

Reputation: 17612

I would replace the scroll view with a UICollectionView. This way you get paging for free, and it will be better, because paging will work out of the box, without you having to calculate the frame offsets.

Be sure to set collectionView.pagingEnabled = true

To get the current page number, do collectionView.indexPathsForVisibleItems().first?.item

To change the page:

collectionView.scrollToItemAtIndexPath(newIndexPath, atScrollPosition: CenteredHorizontally, animated: true)

Upvotes: 0

Related Questions