Xamarin: UIPageControl and UIScrollView for iOS homescreen look

I wanted to add horizontal page swiping to my app similar to what you see on the iOS home screen.  The idea is I will have a menu on the left most screen and as items are added they are given a new page.

To implement this I need to use a UIScrollView to handle the paging and swiping and then a UIPageControl to track which page I’m currently on.  This will be a fairly simple implementation that can be expanded on later.

Firstly add a UIScrollView to a page that is full screen width but about 90% screen height with some room down the bottom of the screen to add the UIPageControl.  On the first page I added a label with “MENU” on it.

Menu

The UIPageControl’s tint color attribute is the color of the dots which i have set to green and the current page color is current selected page which i have set to red.  Also important is the (int)Pages property which is the total number of pages and the (int)CurrentPage.

To setup the UIScrollView paging behavior we check the ‘Paging Enabled’ attribute and the ‘Scrolling Enabled’ attribute.  The UIScrollView will now automatically create pages when content is added to it that sits outside the size of the current view.

Now i will add some dummy content to the view in ViewDidLoad().  This will just be 4 labels “1”,”2″,”3″,”4″ that will be added across the UIScrollView and i will then update the number of pages for the page control and set the ContentSize for the UIScrollView.  The content size is important because its how the UIScrollView works out how many pages it has.

// Dummy Content
int i;

for(i = 1 ; i<5 ; i++)
{
    UILabel label = new UILabel ();
    RectangleF rectangle = new RectangleF ();
    rectangle.X = (this.scrollview1.Frame.Width * i) + 50;
    rectangle.Y = 0;
    rectangle.Size = this.scrollview1.Frame.Size;
    label.Frame = rectangle;
    label.Text = i.ToString ();

    this.scrollview1.AddSubview (label);
}

// set pages and content size
this.pagecontrol1.Pages = i;
scrollview1.ContentSize = new SizeF (scrollview1.Frame.Width * i, scrollview1.Frame.Height);

Currently this will provide the correct paging behavior we want but the UIScrollView and the UIPageControl are not actually linked together.  If you were to swipe page to page nothing will happen to the CurrentPage property of the UIPageControl.  To fix this we attach a method to the UIScrollView scrolled event.

this.scrollview1.Scrolled += ScrollEvent;

Then update the page based on the scrolling ContentOffset divided by the frame width.

private void ScrollEvent(object sender, EventArgs e)
{
    this.pagecontrol1.CurrentPage = 
    (int)System.Math.Floor(scrollview1.ContentOffset.X 
    / this.scrollview1.Frame.Size.Width);
}

Which gives:

Scrolled

Here you can see I have swiped over two screens and everything is working correctly.