Привет, iOS (несколько экранов): краткое руководство

Предупреждение

Поддержка конструктора iOS была прекращена в Visual Studio 2019 версии 16.8 и Visual Studio 2019 для Mac версии 8.8. В Visual Studio 2019 версии 16.9 и Visual Studio для Mac версии 8.9 этот конструктор удален. Создавать пользовательские интерфейсы iOS рекомендуется непосредственно на Mac с помощью Xcode Interface Builder. Дополнительные сведения см. в статье Проектирование пользовательских интерфейсов с помощью Xcode.

В этой части пошагового руководства вы добавите в приложение Phoneword второй экран с журналом телефонных номеров, на которые из приложения совершались звонки. Итоговое приложение будет иметь второй экран с журналом вызовов, как показано на следующем снимке экрана:

The final application will have a second screen that displays the call history, as illustrated by this screenshot

Прилагаемый подробный обзор описывает полученное приложение, а также затрагивает архитектуру, навигацию и другие новые понятия iOS, которые вам встретились.

Требования

Это руководство начинается с того момента, на котором заканчивается документ "Привет, iOS", поэтому вам нужно сначала изучить Привет, iOS: краткое руководство. Скачайте готовую версию приложения Phoneword из примера Привет, iOS.

Пошаговое руководство для macOS

В этом пошаговом руководстве вы добавите в приложение Phoneword экран "Call History" (Журнал вызовов).

  1. Откройте приложение Phoneword в Visual Studio для Mac. При необходимости готовое приложение Phoneword из пошагового руководства Привет, iOS можно скачать здесь.

  2. Откройте файл Main.storyboard из Панели решения:

    The Main.storyboard in the iOS Designer

  3. Перетащите контроллер навигации из панели элементов в область конструктора (чтобы уместить все элементы в этой области, может потребоваться уменьшить масштаб):

    Drag a navigation controller from the Toolbox onto the design surface

  4. Перетащите элемент Sourceless Segue (Переход без источника) (это серая стрелка слева от контроллера представления) в контроллер навигации, чтобы изменить начальную точку приложения:

    Drag the Sourceless Segue to the navigation controller to change the starting point of the application

  5. Выберите существующий контроллер корневого представления, щелкнув нижнюю панель, а затем нажмите клавишу DELETE, чтобы удалить его из области конструктора. Переместите сцену Phoneword к контроллеру навигации:

    Move the Phoneword scene next to the navigation controller

  6. Задайте ViewController в качестве контроллера корневого представления у контроллера навигации. Нажмите и удерживайте клавишу CTRL и щелкните внутри контроллера навигации. Должна появиться синяя линия. Затем, продолжая удерживать клавишу CTRL, перетащите элементы из контроллера навигации в сцену Phoneword. Это называется перетаскиванием с удержанием клавиши CTRL:

    Drag from the navigation controller to the Phoneword scene and release

  7. В контекстном меню задайте связь Корень:

    Setting the relationship to Root

    Теперь ViewController является контроллером корневого представления контроллера навигации:

    The ViewController is now the navigation controllers Root view controller

  8. Дважды щелкните Phoneword экрана заголовок панели и изменить заголовок для Phoneword:

    Change the Title to Phoneword

  9. Перетащите элемент Button из панели элементов и поместите его под элементом Call Button (Кнопка вызова). Перетащите маркеры, чтобы сделать новый элемент Button такой же ширины, что и элемент Call Button (Кнопка вызова):

    Make the new Button the same width as the Call Button

  10. На Панели свойств измените имя кнопки на CallHistoryButton, а заголовок — на Call History:

    Change the Name of the Button to CallHistoryButton and change the Title to Call History

  11. Создайте экран Call History (Журнал вызовов). Перетащите контроллер представления таблиц из панели элементов в область конструктора:

    Drag a table view controller onto the design surface

  12. Затем выберите контроллер представления таблиц, щелкнув черную полосу в нижней части сцены. На Панели свойств измените класс контроллера представления таблиц на CallHistoryController и нажмите клавишу ВВОД:

    Change the table view controllers class to CallHistoryController

    Конструктор iOS создает пользовательский резервный класс CallHistoryController для управления иерархией представлений содержимого на этом экране. На Панели решения появляется файл CallHistoryController.cs:

    The CallHistoryController.cs file in the Solution Pad

  13. Дважды щелкните файл CallHistoryController.cs, чтобы открыть его, и замените содержимое следующим кодом:

    using System;
    using Foundation;
    using 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;
                }
    
                public override nint RowsInSection (UITableView tableView, nint section)
                {
                    return controller.PhoneNumbers.Count;
                }
    
                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;
                }
            }
        }
    }
    

    Сохраните приложение (⌘+S) и выполните его сборку (⌘+B), чтобы убедиться в отсутствии ошибок.

  14. Создайте переход между сценой Phoneword и сценой Журнал вызовов. В сцене Phoneword выберите Кнопка журнала вызовов и, удерживая нажатой клавишу CTRL, перетащите из элемента Кнопка в сцену Журнал вызовов:

    Ctrl-drag from the Button to the Call History scene

    В контекстном меню Action Segue (Переход между действиями) выберите Показать.

    Конструктор iOS добавляет переход между двумя сценами:

    The Segue between the two scenes

  15. Добавьте Заголовок в контроллер представления таблиц, выбрав черную полосу в нижней части сцены и изменив Контроллер представления > Заголовок на Журнал вызовов на Панели свойств:

    Change the view controller title to Call History in the Properties Pad

  16. При запуске приложения Кнопка журнала вызовов откроет экран Журнал вызовов, однако представление таблиц будет пустым, так как отсутствует код для отслеживания и отображения телефонных номеров.

    Это приложение сохраняет телефонные номера в виде списка строк.

    Добавьте директиву using в верхней части ViewControllerSystem.Collections.Generic:

    using System.Collections.Generic;
    
  17. Измените класс ViewController с помощью следующего кода:

    using System;
    using System.Collections.Generic;
    using Foundation;
    using UIKit;
    
    namespace Phoneword_iOS
    {
      public partial class ViewController : UIViewController
      {
        string translatedNumber = "";
    
        public List<string> PhoneNumbers { get; set; }
    
        protected ViewController(IntPtr handle) : base(handle)
        {
          //initialize list of phone numbers called for Call History screen
          PhoneNumbers = new List<string>();
        }
    
        public override void ViewDidLoad()
        {
          base.ViewDidLoad();
          // Perform any additional setup after loading the view, typically from a nib.
    
          TranslateButton.TouchUpInside += (object sender, EventArgs e) => {
            // Convert the phone number with text to a number
            // using PhoneTranslator.cs
            translatedNumber = PhoneTranslator.ToNumber(
              PhoneNumberText.Text);
    
            // Dismiss the keyboard if text field was tapped
            PhoneNumberText.ResignFirstResponder();
    
            if (translatedNumber == "")
            {
              CallButton.SetTitle("Call ", UIControlState.Normal);
              CallButton.Enabled = false;
            }
            else
            {
              CallButton.SetTitle("Call " + translatedNumber,
                UIControlState.Normal);
              CallButton.Enabled = true;
            }
          };
    
          CallButton.TouchUpInside += (object sender, EventArgs e) => {
    
            //Store the phone number that we're dialing in PhoneNumbers
            PhoneNumbers.Add(translatedNumber);
    
            // Use URL handler with tel: prefix to invoke Apple's Phone app...
            var url = new NSUrl("tel:" + translatedNumber);
    
            // otherwise show an alert dialog
            if (!UIApplication.SharedApplication.OpenUrl(url))
            {
              var alert = UIAlertController.Create("Not supported", "Scheme 'tel:' is not supported on this device", UIAlertControllerStyle.Alert);
              alert.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, null));
              PresentViewController(alert, true, null);
            }
          };
        }
    
        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 callHistoryController = segue.DestinationViewController as CallHistoryController;
    
          //set the table view controller’s list of phone numbers to the
          // list of dialed phone numbers
    
          if (callHistoryController != null)
          {
            callHistoryController.PhoneNumbers = PhoneNumbers;
          }
        }
      }
    }
    

    Здесь необходимо обратить внимание на несколько моментов.

    • Переменная translatedNumber перемещена из метода ViewDidLoad и сделана переменной уровня класса.
    • Код CallButton изменен, чтобы добавлять набранные номера в список телефонных номеров с помощью вызова PhoneNumbers.Add(translatedNumber).
    • Добавлен метод PrepareForSegue.

    Сохраните изменения и выполните сборку приложения, чтобы убедиться в отсутствии ошибок.

  18. Нажмите кнопку Запустить, чтобы запустить приложение в симуляторе iOS:

    Press the Start button to launch the application inside the iOS Simulator

Поздравляем! Вы создали свое первое приложение Xamarin.iOS с несколькими экранами!

Пошаговое руководство для Windows

В этом пошаговом руководстве вы добавите в приложение Phoneword экран "Call History" (Журнал вызовов).

  1. Откройте приложение Phoneword в Visual Studio. При необходимости скачайте готовое приложение Phoneword из пошагового руководства Привет, iOS. Не забывайте, что для подключения к Mac нужно использовать конструктор iOS и симулятор iOS.

  2. Сначала измените пользовательский интерфейс. Откройте файл Main.storyboard в обозревателе решений и убедитесь, что в поле Просмотреть как задано значение iPhone 6:

    The Main.storyboard in the iOS Designer

  3. Перетащите контроллер навигации из панели элементов в область конструктора:

    Drag a navigation controller from the Toolbox onto the design surface

  4. Перетащите переход без источника (это серая стрелка слева от сцены Phoneword) из сцены Phoneword на контроллер навигации, чтобы изменить начальную точку приложения:

    Drag the Sourceless Segue to the navigation controller to change the starting point of the application

  5. Выберите контроллер корневого представления, щелкнув черную полосу, а затем нажмите клавишу DELETE, чтобы удалить его из области конструктора. Переместите сцену Phoneword к контроллеру навигации:

    Move the Phoneword scene next to the navigation controller

  6. Задайте ViewController в качестве контроллера корневого представления у контроллера навигации. Нажмите и удерживайте клавишу CTRL и щелкните внутри контроллера навигации. Должна появиться синяя линия. Затем, продолжая удерживать клавишу CTRL, перетащите элементы из контроллера навигации в сцену Phoneword. Это называется перетаскиванием с удержанием клавиши CTRL:

    Drag from the navigation controller to the Phoneword scene and release

  7. В контекстном меню задайте связь Корень:

    Set the relationship to Root

    Теперь ViewController является контроллером корневого представления у контроллера навигации.

  8. Дважды щелкните Phoneword экрана заголовок панели и изменить заголовок для Phoneword:

    Change the Title to Phoneword

  9. Перетащите элемент Button из панели элементов и поместите его под элементом Call Button (Кнопка вызова). Перетащите маркеры, чтобы сделать новый элемент Button такой же ширины, что и элемент Call Button (Кнопка вызова):

    Make the new Button the same width as the Call Button

  10. В обозревателе свойств измените Имя с Button на CallHistoryButton и измените Заголовок на Call History (Журнал вызовов):

    Change the Name of the Button to CallHistoryButton and the Title to Call History

  11. Создайте экран Call History (Журнал вызовов). Перетащите контроллер представления таблиц из панели элементов в область конструктора:

    Drag a table view controller onto the design surface

  12. Выберите контроллер представления таблиц, щелкнув черную полосу в нижней части сцены. В обозревателе свойств измените класс контроллера представления таблиц на CallHistoryController и нажмите клавишу ВВОД:

    Change the table view controllers class to CallHistoryController

    Конструктор iOS создает пользовательский резервный класс CallHistoryController для управления иерархией представлений содержимого на этом экране. В обозревателе решений появляется файл CallHistoryController.cs:

    The CallHistoryController.cs file in the Solution Explorer

  13. Дважды щелкните файл CallHistoryController.cs, чтобы открыть его, и замените содержимое следующим кодом:

    using System;
    using Foundation;
    using UIKit;
    using System.Collections.Generic;
    
    namespace Phoneword
    {
        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;
                }
    
                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;
                }
            }
        }
    }
    

    Сохраните приложение и выполните его сборку, чтобы убедиться в отсутствии ошибок. На данном этапе можно игнорировать любые предупреждения сборки.

  14. Создайте переход между сценой Phoneword и сценой Журнал вызовов. В сцене Phoneword выберите Кнопку журнала вызовов и, удерживая нажатой клавишу CTRL, перетащите из элемента Кнопка в сцену Журнал вызовов:

    Ctrl-drag from the Button to the Call History scene

    В контекстном меню Action Segue (Переход между действиями) выберите Показать:

    Select Show as the segue type

    Конструктор iOS добавляет переход между двумя сценами:

    The Segue between the two scenes

  15. Добавьте заголовок в контроллер представления таблицы, выбрав черную панель в нижней части сцены и изменив заголовок контроллера > представления на журнал вызовов в Обозреватель свойств:

    Change the view controller Title to Call History

  16. При запуске приложения Кнопка журнала вызовов откроет экран Журнал вызовов, однако представление таблиц будет пустым, так как отсутствует код для отслеживания и отображения телефонных номеров.

    Это приложение сохраняет телефонные номера в виде списка строк.

    Добавьте директиву using в верхней части ViewControllerSystem.Collections.Generic:

    using System.Collections.Generic;
    
  17. Измените класс ViewController с помощью следующего кода:

    using System;
    using System.Collections.Generic;
    using Foundation;
    using UIKit;
    
    namespace Phoneword_iOS
    {
      public partial class ViewController : UIViewController
      {
        string translatedNumber = "";
    
        public List<string> PhoneNumbers { get; set; }
    
        protected ViewController(IntPtr handle) : base(handle)
        {
          //initialize list of phone numbers called for Call History screen
          PhoneNumbers = new List<string>();
        }
    
        public override void ViewDidLoad()
        {
          base.ViewDidLoad();
          // Perform any additional setup after loading the view, typically from a nib.
    
          TranslateButton.TouchUpInside += (object sender, EventArgs e) => {
            // Convert the phone number with text to a number
            // using PhoneTranslator.cs
            translatedNumber = PhoneTranslator.ToNumber(
              PhoneNumberText.Text);
    
            // Dismiss the keyboard if text field was tapped
            PhoneNumberText.ResignFirstResponder();
    
            if (translatedNumber == "")
            {
              CallButton.SetTitle("Call ", UIControlState.Normal);
              CallButton.Enabled = false;
            }
            else
            {
              CallButton.SetTitle("Call " + translatedNumber,
                UIControlState.Normal);
              CallButton.Enabled = true;
            }
          };
    
          CallButton.TouchUpInside += (object sender, EventArgs e) => {
    
            //Store the phone number that we're dialing in PhoneNumbers
            PhoneNumbers.Add(translatedNumber);
    
            // Use URL handler with tel: prefix to invoke Apple's Phone app...
            var url = new NSUrl("tel:" + translatedNumber);
    
            // otherwise show an alert dialog
            if (!UIApplication.SharedApplication.OpenUrl(url))
            {
              var alert = UIAlertController.Create("Not supported", "Scheme 'tel:' is not supported on this device", UIAlertControllerStyle.Alert);
              alert.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, null));
              PresentViewController(alert, true, null);
            }
          };
        }
    
        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 callHistoryController = segue.DestinationViewController as CallHistoryController;
    
          //set the table view controller’s list of phone numbers to the
          // list of dialed phone numbers
    
          if (callHistoryController != null)
          {
            callHistoryController.PhoneNumbers = PhoneNumbers;
          }
        }
      }
    }
    

    Здесь необходимо обратить внимание на несколько моментов.

    • Переменная translatedNumber перемещена из метода ViewDidLoad в переменную уровня класса.
    • Код CallButton изменен, чтобы добавлять набранные номера в список телефонных номеров с помощью вызова PhoneNumbers.Add(translatedNumber).
    • Добавлен метод PrepareForSegue.

    Сохраните изменения и выполните сборку приложения, чтобы убедиться в отсутствии ошибок.

    Сохраните изменения и выполните сборку приложения, чтобы убедиться в отсутствии ошибок.

  18. Нажмите кнопку Запустить, чтобы запустить приложение в симуляторе iOS.

    The first screen of the sample app

Поздравляем! Вы создали свое первое приложение Xamarin.iOS с несколькими экранами!

Теперь приложение может обрабатывать навигацию как с помощью переходов, так и в коде. Пришло время закрепить и углубить приобретенные знания и навыки — вас ждет раздел Привет, iOS (несколько экранов). Подробные сведения.