Simon say’s MonoTouch scrolling like iPhone home screen in C#
One of the most popular user experiences on the iPhone is the home screen and how you can slide “pages” into view with all the snappy behaviors. Luckily with the UIScrollViewer control and MonoTouch this is all super simple to implement.
I am going to show you how to put a UIScrollViewer on your view and populate it with 10 labels that will be used for 10 views of which we can scroll. In a real world application you could construct anything you wish in these 10 pages. You could even load new views, with view controller’s.
In a resource hungry application, if these views are too heavy to populate fully, you could easily lazy-load them. You would do this by loading the page previous to the current page, and the page after the current page. This way when you scroll they are visible and as you move pages, pages are dynamically loaded.
In this tutorial we will stay simple with labels to get the points across on what is needed to make this technique work.
We will put the index number on the label as well as alternating colour’s of red and blue to easily see our scrolling. Let’s get started!
First double click your .xib file of the view you wish edit and Interface Builder will be launched. Drag a Scroll Viewer and Page Control on to your view.
Create both a scrollView and pageControl IBOutlet on your AppDelegate or ViewController depending on what view you are editing.
Connect the 2 IBOutlet’s to the actual controls.
Enable paging on the Scroll Viewer. This will give the Scroll Viewer the snap effect the home screen has. Disable horizontal and vertical to hide the scroll bars.
In our AppDelegate or ViewController we are going to create a new method called CreatePanels. This method will populate our Scroll Viewer with 10 items that we can drag our finger to slide into view like the home screen.
We use the Scroll Viewer’s frame to calculate how big each label should be to consume the entire visible area of the Scroll Viewer. We position all of the views that go in the Scroll Viewer with Scroll Viewer width * the counter.
[csharp]
private void CreatePanels()
{
scrollView.Scrolled += ScrollViewScrolled;
int count = 10;
RectangleF scrollFrame = scrollView.Frame;
scrollFrame.Width = scrollFrame.Width * count;
scrollView.ContentSize = scrollFrame.Size;
for (int i=0; i<count; i++)
{
UILabel label = new UILabel();
label.TextColor = UIColor.Black;
label.TextAlignment = UITextAlignment.Center;
label.Text = i.ToString();
if (i % 2 == 0)
label.BackgroundColor = UIColor.Red;
else
label.BackgroundColor = UIColor.Blue;
RectangleF frame = scrollView.Frame;
PointF location = new PointF();
location.X = frame.Width * i;
frame.Location = location;
label.Frame = frame;
scrollView.AddSubview(label);
}
pageControl.Pages = count;
}
[/csharp]
The Page Control is used to allow us to display to the user which page we are currently viewing in the Scroll Viewer. We use the event we hooked up above to alter the current page on the Page Control when the Scroll Viewer is scrolled to a new “page”. The page control is the same control you see on the home screen which displays the little white dots indicating which page you are looking at.
[csharp]
private void ScrollViewScrolled (object sender, EventArgs e)
{
double page = Math.Floor((scrollView.ContentOffset.X – scrollView.Frame.Width / 2) / scrollView.Frame.Width) + 1;
pageControl.CurrentPage = (int)page;
}
[/csharp]
And there we have it. A user interface that behaves exactly as the home screen scrolling effect!
Please retweet and feel free to follow me @simongui on Twitter at http://www.twitter.com/simongui
Tags: iPhone .NET MonoTouch Mono
Trackback from your site.





Comments (9)
Alex York
| #
Very nice! A good simple example too with no clutter. Keep it up.
Reply
CraigD
| #
Simon, I think the UIPageControl can also change the view (by a touch to the left or right ends of the dots). This seems to work in the Simulator with the following code addition (in FinishedLaunching):
pageControl.ValueChanged += delegate(object sender, EventArgs e) {
var pc = (UIPageControl)sender;
double fromPage = Math.Floor((scrollView.ContentOffset.X – scrollView.Frame.Width / 2) / scrollView.Frame.Width) + 1;
var toPage = pc.CurrentPage;
var pageOffset = scrollView.ContentOffset.X + scrollView.Frame.Width;
Console.WriteLine("fromPage " + fromPage + " toPage " + toPage);
if (fromPage > toPage)
pageOffset = scrollView.ContentOffset.X – scrollView.Frame.Width;
PointF p = new PointF(pageOffset, 0);
scrollView.SetContentOffset(p,true);
};
Reply
Russell
| #
I did everything you said, and it is showing this error.
error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void'
PLZ HELP
Reply
Hwoof
| #
Thanks for this demo – superb – helped me a lot (plus also the tip from Craig – that will allow me to do lazy loading of views – much appreciated!)
Reply
huseyin
| #
Can we apply only using mono too? not monotouch?
Reply
Aaron Williams
| #
Thanks for the example!
Reply
superyeti420
| #
Hi Guys, great example. I made a small change to the button code, if you were pressing the buttons really quickly you could get the event to fire more than once at the last page. it was being calculated based on the current offset which caused issues, i changed it to use the page# * page width to get the correct display all the time. Include this code in the FinishedLoading method.
pageControl.ValueChanged += delegate(object sender, EventArgs e) {
var pc = (UIPageControl)sender;
double fromPage = Math.Floor((scrollView.ContentOffset.X – scrollView.Frame.Width / 2) / scrollView.Frame.Width) + 1;
var toPage = pc.CurrentPage;
var pageOffset = scrollView.Frame.Width*toPage;
Console.WriteLine("fromPage " + fromPage + " toPage " + toPage);
PointF p = new PointF(pageOffset, 0);
scrollView.SetContentOffset(p,true);
};
Reply
Appan
| #
hi, shal u provide information of fast scrolling (through mouse wheel or key board) on our own user controls created in c#. control created by painting. scrolling action is available but not as fast as apple iphone scrolling.please provide information
Reply
richardpniewski
| #
Awesome tutorial! Can you by any chance change the height of the UIPageController (the dots area)? Or is it permanently 36? Because I really wanted to make is shorter (thinner) so it takes up less room on my screen. I know I can make the UIPageController transparent, but I don't want it transparent.
THANKS!
Reply