James Montemagno b117c7b1c1 Initial Commit 10 年之前
..
Images b117c7b1c1 Initial Commit 10 年之前
readme.md b117c7b1c1 Initial Commit 10 年之前

readme.md

id:{d72e6230-c9ee-4bee-90ec-877d256821}
title:Hello, iOS Multiscreen
subtitle:Handling Navigation with Xamarin.iOS
brief:In this two-part guide, we expand the Phoneword application we created in the Hello, iOS guide to handle a second screen. Along the way we’ll introduce the Model-View-Controller design pattern, implement our first iOS navigation, and develop a deeper understanding of iOS application structure and functionality.
samplecode:Hello, iOS
sdk:iOS Human Interface Guidelines
sdk:iOS Provisioning Portal

Hello.iOS Multiscreen Quickstart

In the walkthrough part of this guide we’ll add a second screen to our Phoneword application to keep track of the history of numbers called using our app. The final application will have a second screen that displays the call history, as illustrated by the following screenshot:

In the accompanying Deep Dive, we’ll review what we’ve built and discuss architecture, navigation, and other new iOS concepts that we encounter along the way. Let’s get started!

Requirements

This guide resumes where the Hello, iOS document left off, and requires completion of the Hello, iOS Quickstart. If you’d like to jump directly into the Hello, iOS Multiscreen Quickstart, you can download the completed version of the Phoneword app from the Hello, iOS sample.

Walkthrough – Navigation with Segues

In this walkthrough we’ll add a Call History screen to our Phoneword application.

  1. Let’s open the Phoneword application in Visual Studio. If you haven’t completed the Hello, iOS walkthrough, you can download the completed Phoneword application here:

  2. Let’s start by editing the user interface. Open the MainStoryboard.storyboard file from the Solution Explorer:

  3. Next, let’s drag a Navigation Controller from the Toolbox onto the design surface:

  4. Drag the Sourceless Segue (that’s the gray arrow to the left of the Phoneword Scene) from the Phoneword Scene to the Navigation Controller to change the starting point of the application:

  5. Select the Root View Controller by clicking on the black bar, and press Delete to remove it from the design surface.

    Then, let’s move the Phoneword Scene next to the Navigation Controller:

  6. Next, let’s set the ViewController as the Navigation Controller’s Root View Controller. Press down the Ctrl key and click inside the Navigation Controller. A blue line should appear. Then, still holding down the Ctrl key, drag from the Navigation Controller to the Phoneword Scene and release. This is called Ctrl-dragging:

  7. From the popover, let’s set the relationship to Root:

    The ViewController is now our Navigation Controller’s Root View Controller:

  8. Double-click on the Phoneword screen’s Title bar and change the Title to "Phoneword":

  9. Let’s drag a Button from the Toolbox and place it under the Call Button. Drag the handles to make the new Button the same width as the Call Button:

  10. In the Properties Explorer, change the Name of the Button to CallHistoryButton and change the Title to "Call History":

  11. Next, let’s create the Call History screen. From the Toolbox, drag a Table View Controller onto the design surface:

  12. Next, select the Table View Controller by clicking on the black bar at the bottom of the Scene. In the Properties Explorer, change the Table View Controller’s class to CallHistoryController and press Enter:

    The iOS Designer will generate a custom backing class called CallHistoryController to manage this screen’s Content View Hierarchy. The CallHistoryController.cs file will appear in the Solution Explorer:

  13. Let’s double-click on the CallHistoryController.cs file to open it and replace the contents with the following code:

    using System;
    using MonoTouch.Foundation;
    using MonoTouch.UIKit;
    using System.Collections.Generic;
    
    namespace Phoneword_iOS
    {
        public partial class CallHistoryController : UITableViewController
        {
            public List<String> PhoneNumbers { get; set; }
    
            static NSString callHistoryCellId = new NSString ("CallHistoryCell");
    
            public CallHistoryController (IntPtr handle) : base (handle)
            {
                TableView.RegisterClassForCellReuse (typeof(UITableViewCell), callHistoryCellId);
                TableView.Source = new CallHistoryDataSource (this);
                PhoneNumbers = new List<string> ();
            }
    
            class CallHistoryDataSource : UITableViewSource
            {
                CallHistoryController controller;
    
                public CallHistoryDataSource (CallHistoryController controller)
                {
                    this.controller = controller;
                }
    
                // Returns the number of rows in each section of the table
                public override nint RowsInSection (UITableView tableView, nint section)
                {
                    return controller.PhoneNumbers.Count;
                }
                //
                // Returns a table cell for the row indicated by row property of the NSIndexPath
                // This method is called multiple times to populate each row of the table.
                // The method automatically uses cells that have scrolled off the screen or creates new ones as necessary.
                //
                public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
                {
                    var cell = tableView.DequeueReusableCell (CallHistoryController.callHistoryCellId);
    
                    int row = indexPath.Row;
                    cell.TextLabel.Text = controller.PhoneNumbers [row];
                    return cell;
                }
            }
        }
    }

    Save the application and build it to ensure there are no errors.

  14. Let’s create a Segue (transition) between the Phoneword Scene and the Call History Scene. In the Phoneword Scene, select the Call History Button and Ctrl-drag from the Button to the Call History Scene:

    From the Action Segue popover, select Push:

    The iOS Designer will add a Segue between the two Scenes:

  15. Let’s add a Title to the Table View Controller by selecting the black bar at the bottom of the Scene and changing the View Controller Title to "Call History"" in the Properties Explorer:

  16. If we run the application now, the Call History Button will open the Call History screen, but the Table View will be empty because we have no code to keep track of phone numbers. Let’s add that functionality.

    First, we need a way to store dialed phone numbers. We’re going to store it as a list of strings called PhoneNumbers.

    To support lists, let’s add System.Collections.Generic to our using directives at the top of the file:

    using System.Collections.Generic;
  17. Next, modify the ViewController class with the following code:
    namespace Phoneword_iOS
    {
        public partial class ViewController : UIViewController
        {
            // translatedNumber was moved here from ViewDidLoad ()
            string translatedNumber = "";
    
            public List<String> PhoneNumbers { get; set; }
    
            public ViewController (IntPtr handle) : base (handle)
            {
                //initialize list of phone numbers called for Call History screen
                PhoneNumbers = new List<String> ();
    
            }
            // ViewDidLoad, etc...
        }
    }

    Note that we’ve also moved translatedNumber from inside the ViewDidLoad method to a class-level variable.

  18. Next, let’s modify our CallButton code to add dialed numbers to the list of phone numbers by calling PhoneNumbers.Add(translatedNumber). The full code will look like this:

    // On "Call" button-up, try to dial a phone number
    CallButton.TouchUpInside += (object sender, EventArgs e) => {
    
        //Store the phone number that we're dialing in PhoneNumbers
        PhoneNumbers.Add (translatedNumber);
    
        var url = new NSUrl ("tel:" + translatedNumber);
    
        if (!UIApplication.SharedApplication.OpenUrl (url)) {
            var av = new UIAlertView ("Not supported",
                     "Scheme 'tel:' is not supported on this device",
                      null,
                      "OK",
                      null);
            av.Show ();
        }
     };
  19. Finally, let’s add the following method to the ViewController class. This will go somewhere below ViewDidLoad:

    public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
      {
         base.PrepareForSegue (segue, sender);
    
         // set the View Controller that’s powering the screen we’re
         // transitioning to
    
         var callHistoryContoller = segue.DestinationViewController as CallHistoryController;
    
         //set the Table View Controller’s list of phone numbers to the
         // list of dialed phone numbers
    
         if (callHistoryContoller != null) {
            callHistoryContoller.PhoneNumbers = PhoneNumbers;
         }
       }

    Save and build the application to make sure there are no errors.

  20. Press the Start button to launch our application inside the iOS Simulator:

  21. Congratulations on completing your first multi-screen Xamarin.iOS application!

    Walkthrough - Code-Only Navigation

    In the walkthrough above, we created navigation between the Phoneword and Call History screens using a Storyboard Segue. Segues are great at handling simple navigation that requires moving from one screen to the next. Segues are not good at handling more complex navigation – for example, conditional navigation when the second screen may be different depending on the user’s behavior on the first screen. In this walkthrough, we’ll learn to handle navigation between screens programmatically.

    1. Let’s the MainStoryboard.storyboard file and remove the Segue between the Phoneword Scene and the Call History Scene by selecting the Segue and pressing Delete:

    2. This will remove the Title Bar and Back Button from the Call History screen.

    3. Select the CallHistoryController by clicking on the black bar at the bottom of the Scene. In the Properties Explorer, let’s set this View Controller’s Storyboard ID to CallHistoryController:

    4. Next, in the ViewController class, let’s remove the PrepareForSegue method we added in the previous walkthrough. We can comment out the entire method it by selecting the code, clicking the Edit Menu and choosing Advanced > Comment Selection:

    5. Add the following code inside the ViewDidLoad method. This wires up the CallHistoryButton to perform the navigation to the next screen:

      CallHistoryButton.TouchUpInside += (object sender, EventArgs e) =>{
         // Launches a new instance of CallHistoryController
         CallHistoryController callHistory = this.Storyboard.InstantiateViewController ("CallHistoryController") as CallHistoryController;
         if (callHistory != null) {
            callHistory.PhoneNumbers = PhoneNumbers;
         this.NavigationController.PushViewController (callHistory, true);
         }
      };

      Save and build the application to make sure there are no errors.

    6. Press the Start button to launch our application inside the iOS Simulator. It should look and behave exactly the same as the previous version:

    Our app can now handle navigation using both Storyboard Segues and in code. Now it’s time to dissect the tools and skills we just learned in the Hello, iOS Multiscreen Deep Dive.