Using segues and UITableView

A segue is a transition from one controller to another. In the same way, a storyboard file is a collection of controllers and their views attached together by segues. This in turn allows you to see the layouts of each controller and the general flow of your application at the same time.

There are just a few categories of segue, which are as follows:

  • Push: This is used within a navigation controller. It pushes a new controller to the top of the navigation controller's stack. Push uses the standard animation on iOS for navigation controllers and is generally the most commonly used segue.
  • Relationship: This is used to set a child controller of another controller. For example, the root controller of a navigation controller, container views, or split view controllers in an iPad application.
  • Modal: On using this, a controller presented modally will appear on top of the parent controller. It will cover the entire screen until dismissed. There are several types of different transition animations available.
  • Custom: This is a custom segue that includes an option for a custom class, which subclasses UIStoryboardSegue. This gives you fine-grained control over the animation and how the next controller is presented.

Segues also follow the following pattern while executing:

  • The destination controller and its views are created.
  • The segue object, a subclass of UIStoryboardSegue, is created. This is normally only important for custom segues.
  • The PrepareForSegue method is called on the source controller. This is a good place to run any custom code before a segue begins.
  • The segue's Perform method is called and the transition animation is started. This is where the bulk of the code resides for a custom segue.

In Xcode you have the choice of either firing a segue automatically from a button or table view row, or just giving the segue an identifier. In the second case, you can start the segue yourself by calling the PerformSegue method on the source controller by using its identifier.

Now let's set up a new segue by setting up some aspects of our MainStoryboard.storyboard file, by performing the following steps:

  1. Double-click on the MainStoryboard.storyboard file to open it in Xcode.
  2. Add a new Table View Controller to the storyboard.
  3. Select your view controller and click on the Identity Inspector tab. It is the third tab from the left, located on the right-hand side of the screen.
  4. Under the Custom Class section, enter ConversationsController into the Class field.
  5. Create a segue from LoginController to ConversationsController by right-clicking and dragging the blue line from one controller to the other.
  6. Select the push segue from the pop up that appears.
  7. Select the segue by clicking on it and give it an identifier of OnLogin. You'll find this under the Attributes Inspector tab on the right-hand side of the screen.
  8. Save the storyboard file and return to Xamarin Studio.

Open LoginController.cs, and modify the line of code that we marked as TODO earlier in this chapter as follows:

PerformSegue("OnLogin", this);

Now if you build and run the application, you will navigate to the new controller after a successful log in. The segue will be performed, and you will see the built-in animation provided by the navigation controller.

Next, let's set up the table view on the second controller. We are using a powerful class on iOS called UITableView. It is used in many situations and is very similar to the concept of a list view on other platforms. The UITableView class is controlled by another class called UITableViewSource. It has methods that you need to override to set up how many rows should exist and how those rows should be displayed on the screen.

Tip

Note that UITableViewSource is a combination of UITableViewDelegate and UITableViewDataSource. I prefer to use UITableViewSource for simplicity, since many times using both of the other two classes would be required.

Before we jump in and start coding, let's review the most commonly used methods on UITableViewSource, which are as follows:

  • RowsInSection: This method allows you to define the number of rows in a section. All table views have a number of sections and rows. By default, there is only one section; however, it is a requirement to return the number of rows in a section.
  • NumberOfSections: This is the number of sections in the table view.
  • GetCell: This method must return a cell for each row. It is up to the developer to set up what a cell should look like; you can also implement code to recycle the cells as you scroll. Recycling cells will yield better performance while scrolling.
  • TitleForHeader: This method, if overridden, is the simplest way to return a string for the title. Each section in a table view can has a standard header view by default.
  • RowSelected: This method will be called when the user selects a row.

There are additional methods that you can override, but these will get you by in most situations. You can also set up custom headers and footers if you need to develop a custom styled table view.

Now let's open the ConversationsController.cs file, and create a nested class inside ConversationsController as follows:

class TableSource : UITableViewSource
{
  const string CellName = "ConversationCell";
  readonly MessageViewModel messageViewModel =ServiceContainer.Resolve<MessageViewModel>();

  public override int RowsInSection(UITableView tableView, int section)
  {
    return messageViewModel.Conversations == null ?0 : messageViewModel.Conversations.Length;
  }

  public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
  {
    var conversation =messageViewModel.Conversations[indexPath.Row];
    var cell = tableView.DequeueReusableCell(CellName);
    if (cell == null)
    {
      cell = new UITableViewCell(UITableViewCellStyle.Default, CellName);
      cell.Accessory =UITableViewCellAccessory.DislosureIndicator;
    }
    cell.TextLabel.Text = conversation.Username;
    return cell;
  }
}

We implemented the two required methods for setting up a table view: RowsInSection and GetCell. We returned the number of conversations found on the view model and set up our cell for each row. We also used UITableViewCellAccessory.DislosureIndicator to add an indicator for the users know they can click on the row.

Notice our implementation of recycling cells. Calling DequeueReusableCell with a cell identifier will return a null cell the first time around. If null, you should create a new cell using the same cell identifier. Subsequent calls to DequeueReusableCell will return an existing cell if available, enabling you to reuse it. You can also define UITableView cells in the storyboard file, which is useful for custom cells. Our cell here is very simple, so it is easier to define it from C# code. Recycling cells is important on mobile platforms to preserve memory and provide the user with a very fluid scrolling table.

Next, we need to set up the TableView source on TableView. Add some changes to our ConversationsController class as follows:

readonly MessageViewModel messageViewModel =ServiceContainer.Resolve<MessageViewModel>();

public override void ViewDidLoad()
{
  base.ViewDidLoad();

  TableView.Source = new TableSource();
}

public async override void ViewWillAppear()
{
  base.ViewWillAppear ();

  try
  {
    await messageViewModel.GetConversations();

    TableView.ReloadData();
  }
  catch(Exception exc)
  {
    new UIAlertView("Oops!", exc.Message, null, "Ok").Show();
  }
}

So when the view appears, we will load our list of conversations. Upon completion of that task, we'll reload the table view so that it displays our list of conversations. If you run the application, you'll see a few conversations appear in the table view after logging in, as shown in the following screenshot. Down the road, everything will operate in the same manner when we load the conversations from a real web service.

Using segues and UITableView
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.112.69