Using UIScrollView and UIPageControl in RubyMotion
As a new user of UIKit and RubyMotion, I chose the simplest thing to implement on a project that I have to work on (hooray for learning on the job), which looks like this (sorry I couldn't get it to animate in CoderWall):
I put both the UIScollView
and UIPageControl
elements in a view controller, and off we go:
class SlideshowController < UIViewController
def viewDidLoad
super
numberOfPages = 3
@scrollView = UIScrollView.alloc.init
@scrollView.frame = CGRectMake(0, 0, App.window.frame.size.width, App.window.frame.size.height)
@scrollView.pagingEnabled = true
@scrollView.backgroundColor = UIColor.blackColor
@scrollView.contentSize = CGSizeMake(@scrollView.frame.size.width * numberOfPages, @scrollView.frame.size.height)
@scrollView.showsHorizontalScrollIndicator = false
@scrollView.showsVerticalScrollIndicator = false
numberOfPages.times do |i|
view = UIView.alloc.initWithFrame(CGRectMake(@scrollView.frame.size.width * i, 0, @scrollView.frame.size.width, @scrollView.frame.size.height))
view.backgroundColor = UIColor.alloc.initWithPatternImage(UIImage.imageNamed("slideshow-#{i + 1}"))
@scrollView.addSubview(view)
end
@scrollView.delegate = self
self.view.addSubview @scrollView
@pageControl = UIPageControl.alloc.init
@pageControl.frame = CGRectMake(0, 0, App.window.frame.size.width, 80)
@pageControl.numberOfPages = numberOfPages
@pageControl.currentPage = 0
self.view.addSubview @pageControl
end
def scrollViewDidScroll(scrollView)
@pageControl.currentPage = @scrollView.contentOffset.x / @scrollView.frame.size.width
end
end
Essentially, you have to create a scroll view with a content size that maps your entire slideshow. You then create views that you position in your scroll view, and then you let the library do its magic.
To link it up with the page control, you just handle the scrollViewDidScroll
delegate method to set the currentPage
attribute.
I was also trying to allow users to tap on the page control element to jump to specific pages, but struggled with some issue with it, I added another delegate method here:
def clickPageControl(sender)
frame = @scrollView.frame
frame.origin.x = frame.size.width * @pageControl.currentPage
@scrollView.scrollRectToVisible(frame, animated: true)
end
And I hooked it up with the page control like so in viewDidLoad
:
@pageControl.addTarget(self, action: "clickPageControl:", forControlEvents: UIControlEventAllEvents)
The problem with this was that when clickPageControl
was called, it would start scrolling the scroll view, which would in turn trigger scrollViewDidScroll
, and the page control would do some back-and-forth thing which didn't look so great.
Any ideas on fixing that?
UPDATE: I fixed that by using the scrollViewDidEndDecelerating
delegate, which only gets called when it finishes decelerating as it name implies, instead of scrollViewDidScroll
.
Reference(s):