iOS Development with Xamarin Cookbook
上QQ阅读APP看书,第一时间看更新

Navigating through the content divided into pages

In this recipe, we will learn how to use the UIPageControl class to provide page navigation.

Getting ready

The UIPageControl provides a simple visual representation of multiple pages or screens in an iOS app, which is indicated by dots. The following screenshot shows an example of the page control indicating that content is divided into three pages:

Getting ready

The dot that corresponds to the current page is highlighted. It is usually combined with UIScrollView. Create a new iPhone Single View Application project in Xamarin Studio and name it PageNavApp. Add three image files in the project and set their Build Action to BundleResource.

How to do it...

The following are the steps to create this project:

  1. Open the PageNavAppViewController.xib file in Interface Builder.
  2. Add UIPageControl to the bottom of the view and UIScrollView above it. Resize the scroll view to take up all the remaining space of the view and save the document.
  3. Back in Xamarin Studio, enter the following code in the PageNavAppViewController class:
    UIImageView page1;
    UIImageView page2;
    UIImageView page3;
    public override void ViewDidLoad()
    {
      base.ViewDidLoad();
      this.scrollView.DecelerationEnded += this.ScrollView_DecelerationEnded;
      this.pageControl.ValueChanged += this.PageControl_ValueChanged;
      this.scrollView.Scrolled += delegate {
        Console.WriteLine ("Scrolled!");
      } ;
    
      this.scrollView.PagingEnabled = true;
    
      RectangleF pageFrame = this.scrollView.Frame;
      this.scrollView.ContentSize = new SizeF (pageFrame.Width * 3, pageFrame.Height);
    
      this.page1 = new UIImageView (pageFrame);
     this.page1.ContentMode = UIViewContentMode.ScaleAspectFit;
      this.page1.Image = UIImage.FromFile ("Parga01.jpg");
    
      pageFrame.X += this.scrollView.Frame.Width;
      this.page2 = new UIImageView (pageFrame);
      this.page2.ContentMode = UIViewContentMode.ScaleAspectFit;
      this.page2.Image = UIImage.FromFile ("Parga02.jpg");
    
      pageFrame.X += this.scrollView.Frame.Width;
      this.page3 = new UIImageView (pageFrame);
      this.page3.ContentMode = UIViewContentMode.ScaleAspectFit;
      this.page3.Image = UIImage.FromFile ("Parga03.jpg");
    
      this.scrollView.AddSubview (this.page1);
      this.scrollView.AddSubview (this.page2);
      this.scrollView.AddSubview (this.page3);
    
    }
  4. Add the following methods in the class:
    private void scrollView_DecelerationEnded (object sender, EventArgs e)
    {
      float x1 = this.page1.Frame.X;
      float x2 = this.page2.Frame.X;
    
      float x = this.scrollView.ContentOffset.X;
    
      if (x == x1)
      {
        this.pageControl.CurrentPage = 0;
      }  else if (x == x2)
      {
        this.pageControl.CurrentPage = 1;
      }  else
      {
        this.pageControl.CurrentPage = 2;
    
      }
    
    }
    
    private void pageControl_ValueChanged (object sender, EventArgs e)
    {
    
      PointF contentOffset = this.scrollView.ContentOffset;
    
      switch (this.pageControl.CurrentPage)
      {
    
        case 0:
        contentOffset.X = this.page1.Frame.X;
        this.scrollView.SetContentOffset (contentOffset, true);
        break;
    
        case 1:
        contentOffset.X = this.page2.Frame.X;
        this.scrollView.SetContentOffset (contentOffset, true);
        break;
    
        case 2:
        contentOffset.X = this.page3.Frame.X;
        this.scrollView.SetContentOffset (contentOffset, true);
        break;
    
        default:
        // do nothing
        break;
      }
    
    }
  5. Compile and run the app on the simulator. Scroll sideways on the scroll view to change the page. Likewise, tap or scroll on the page control to change the page.

How it works...

The first thing that we need to do is set the UIScrollView.PagingEnabled property to true, as shown in the following code:

this.scrollView.PagingEnabled = true;

This property instructs the scroll view to stop scrolling at multiples of the scroll view's bounds, hence providing paging functionality. After this, the image views that will be displayed on different pages are prepared. Here, we take care of adjusting each image view's frame so that they will be positioned next to each other, using the following code:

this.page1 = new UIImageView (pageFrame);

// Frame for 2nd page
pageFrame.X += this.scrollView.Frame.Width;

// Frame for 3rd page
pageFrame.X += this.scrollView.Frame.Width;

We have attached handlers for two events. The first one is the UIScrollView.DecelerationEnded event, which will adjust the page control's current page when the user scrolls the scroll view. The current page is determined by the scroll view's ContentOffset property, as shown in the following code:

float x = this.scrollView.ContentOffset.X;
if (x == x1) {
  // First page
  this.pageControl.CurrentPage = 0;
// etc.

The second event to which we attach a handler is the UIPageControl.ValueChanged event. In this handler, we make sure that the content is scrolled when the user taps or drags on the page control. The scrolling action is performed when the ContentOffset property is set to the desired image view's Frame.X property using the UIScrollView.SetContentOffset(PointF, bool) method, as shown in the following code:

case 0:
  // Scroll to first page
  contentOffset.X = this.page1.Frame.X;
    this.scrollView.SetContentOffset (contentOffset, true);
  break;
// etc.

The second parameter of the SetContentOffset method instructs the scroll view to animate while scrolling.

There's more...

In this recipe, different UIImageView objects have been used. Any kind of UIView object can be used according to the type of content we want to display.

Proper usage of UIPageControl

Users expect that scrolling to other pages will occur when tapping or dragging on the page control. It is not a good practice to use it for displaying page indexing only.

See also

  • The Displaying images recipe
  • The Displaying content larger than the screen recipe