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:
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:
UIStoryboardSegue
, is created. This is normally only important for custom segues.PrepareForSegue
method is called on the source controller. This is a good place to run any custom code before a segue begins.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:
MainStoryboard.storyboard
file to open it in Xcode.ConversationsController
into the Class field.LoginController
to ConversationsController
by right-clicking and dragging the blue line from one controller to the other.OnLogin
. You'll find this under the Attributes Inspector tab on the right-hand side of the screen.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.
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.
52.15.112.69