Hello,iOS - 快速入门

警告

iOS Designer 在 Visual Studio 2019 版本 16.8 和 Visual Studio 2019 for Mac 版本 8.8 中已经弃用,并且已从 Visual Studio 2019 版本 16.9 和 Visual Studio for Mac 版本 8.9 中移除。 要生成 iOS 用户界面,建议直接在运行 Xcode 的 Interface Builder 的 Mac 上操作。 有关详细信息,请参阅用 Xcode 设计用户界面

本指南介绍如何创建一个应用程序,它将用户输入的字母数字电话号码转换为数字电话号码,然后呼叫该号码。 最终应用程序如下所示:

The Hello.iOS Quickstart app

要求

使用 Xamarin 进行 iOS 开发需要:

  • 运行 macOS High Sierra (10.13) 或更高版本的 Mac。
  • App Store 安装的最新版本 Xcode 和 iOS SDK。

Xamarin.iOS 适用于以下设置:

  • 符合以上规范的最新版本 Visual Studio for Mac。

Xamarin.iOS Mac 安装指南提供了分步安装说明

Xamarin.iOS 适用于以下设置:

  • Windows 10 上的最新版 Visual Studio 2019 或 Visual Studio 2017 Community、Visual Studio 2017 Professional 或 Visual Studio 2017 Enterprise,与符合以上规范的 Mac 生成主机相配合。

Xamarin.iOS Windows 安装指南提供了分步安装说明。

开始之前,请下载 Xamarin 应用图标集

Visual Studio for Mac 演练

本演练介绍如何创建一个名为 Phoneword 的应用程序,它将字母数字电话号码转换为数字电话号码。

  1. 从“应用程序”文件夹或 Spotlight 启动 Visual Studio for Mac

    The Launch screen

    在“启动屏幕”中,单击“新项目...”以创建新的 Xamarin.iOS 解决方案:

    iOS solution

  2. 从“新建解决方案”对话框中,选择 iOS > 应用>单一视图应用程序模板,确保已选择 C# 。 单击“下一步”

    Choose Single View Application

  3. 配置应用。 为其提供名称Phoneword_iOS,并使其他项保留为默认值。 单击“下一步”

    Enter the app name

  4. 将项目和解决方案名称保留为原样。 在此处选择项目的位置,或将它保留为默认值:

    Choose the location of the project

  5. 单击“创建”制定解决方案

  6. 通过在“解决方案板”中双击 Main.storyboard 文件来打开它。 确保使用 Visual Studio iOS 设计器打开文件(右键单击情节提要并选择“使用 iOS 设计器打开”>)。 这提供了一种直观创建 UI 的方法:

    The iOS Designer

    注意,默认情况下会启用“大小类”。 请参阅统一情节提要指南以了解有关它们的详细信息。

  7. 在“Toolbox Pad”中,向搜索栏键入“标签”并将一个“标签”拖动到设计图面上(中央区域):

    Drag a Label onto the design surface the area in the center

    注意

    可以通过导航到 View Pad 随时打开 Properties Pad工具箱。>

  8. 抓取拖动控件的图柄(控件周围的圆圈)并使标签更宽:

    Make the label wider

  9. 在设计图面上选择了“标签”的情况下,使用“属性板”将“标签”的“文本”属性更改为“Enter a Phoneword:”

    Set the label to Enter a Phoneword

  10. 在工具箱内搜索“文本字段”,将一个“文本字段”从“工具箱”拖动到设计图面上,并将它放置在“标签”下方。 调整宽度,直到“文本字段”的宽度与“标签”相同:

    Make the Text Field the same width as the Label

  11. 在设计图面上选择了“文本字段”的情况下,在“Properties Pad”的“标识”部分中将“文本字段”的“名称”属性更改为 PhoneNumberText,并将“文本”属性更改为“1-855-XAMARIN”:

    Change the Title property to 1-855-XAMARIN

  12. 将一个“按钮”从“工具箱”拖动到设计图面上,并将它放置在“文本字段”下方。 调整宽度,以便“按钮”与“文本字段”和“标签”一样宽:

    Adjust the width so the Button is as wide as the Text Field and Label

  13. 在设计图面上选择了“按钮”的情况下,在“属性板”的“标识”部分中将“名称”属性更改为 TranslateButton。 将“标题”属性更改为“Translate”:

    Change the Title property to Translate

  14. 重复上面的两个步骤,将一个“按钮”从“工具箱”拖动到设计图面上,并将它放置第一个“按钮”下方。 调整宽度,以便该“按钮”与第一个“按钮”一样宽:

    Adjust the width so the Button is as wide as the first Button

  15. 在设计图面上选择了第二个“按钮”的情况下,在“属性板”的“标识”部分中将“名称”属性更改为 CallButton。 将“标题”属性更改为“Call”:

    Change the Title property to Call

    通过导航到“文件保存”或按 ⌘ + s 保存更改。>

  16. 需要将一些逻辑添加到应用,以便将电话号码为字母数字转换为数字。 通过在 Solution Pad 中右键单击电话word_iOS项目并选择“添加新>文件...”或按 ⌘ + n,将新文件添加到项目:

    Add a new file to the Project

  17. “新建文件 ”对话框中,选择“ 常规 > 空类 ”并命名新文件 PhoneTranslator

    Select Empty Class and name the new file PhoneTranslator

  18. 这会为我们创建新的空 C# 类。 删除所有模板代码并替换为以下代码:

    using System.Text;
    using System;
    
    namespace Phoneword_iOS
    {
        public static class PhoneTranslator
        {
            public static string ToNumber(string raw)
            {
                if (string.IsNullOrWhiteSpace(raw)) {
                    return "";
                } else {
                    raw = raw.ToUpperInvariant();
                }
    
                var newNumber = new StringBuilder();
                foreach (var c in raw)
                {
                    if (" -0123456789".Contains(c)) {
                        newNumber.Append(c);
                    } else {
                        var result = TranslateToNumber(c);
                        if (result != null) {
                            newNumber.Append(result);
                        }
                    }
                    // otherwise we've skipped a non-numeric char
                }
                return newNumber.ToString();
            }
    
            static bool Contains (this string keyString, char c)
            {
                return keyString.IndexOf(c) >= 0;
            }
    
            static int? TranslateToNumber(char c)
            {
                if ("ABC".Contains(c)) {
                    return 2;
                } else if ("DEF".Contains(c)) {
                    return 3;
                } else if ("GHI".Contains(c)) {
                    return 4;
                } else if ("JKL".Contains(c)) {
                    return 5;
                } else if ("MNO".Contains(c)) {
                    return 6;
                } else if ("PQRS".Contains(c)) {
                    return 7;
                } else if ("TUV".Contains(c)) {
                    return 8;
                } else if ("WXYZ".Contains(c)) {
                    return 9;
                }
                return null;
            }
        }
    }
    

    保存 PhoneTranslator.cs 文件并关闭它。

  19. 添加代码以关联用户界面。 若要执行此操作,请在“解决方案板”中双击 ViewController.cs以打开它:

    Add code to wire up the user interface

  20. 首先关联 TranslateButton。 在 ViewController 类中,找到 ViewDidLoad 方法并在 base.ViewDidLoad() 调用下方添加以下代码:

    string translatedNumber = "";
    
    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;
        }
    };
    

    如果文件的命名空间不同,则包括 using Phoneword_iOS;

  21. 添加代码以响应按第二个按钮的用户(名为 CallButton)。 将以下代码置于 TranslateButton 的代码下方,并将 using Foundation; 添加到文件顶部:

        CallButton.TouchUpInside += (object sender, EventArgs e) => {
            // 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);
            }
        };
    
  22. 保存更改,然后选择“全部生成>或按 ⌘ + B 生成应用程序。如果应用程序编译,IDE 顶部将显示一条成功消息:

    A success message will appear at the top of the IDE

    如果发生错误,则完成前面的步骤并更正任何错误,直到应用程序成功生成。

  23. 最后,在 iOS 模拟器中测试应用程序。 在 IDE 左上角,从第一个下拉菜单中选择“调试”,并从第二个下拉菜单中选择“iPhone XR iOS 12.0”(或其他可用的模拟器),然后按“启动”(类似于“播放”按钮的三角形按钮)

    Select a simulator and press start

    注意

    目前,Apple 可能要求拥有开发证书或签名标识才能为设备或模拟器生成代码。 请按照设备预配指南中的步骤执行此设置。

  24. 这会在 iOS 模拟器中启动应用程序:

    The application running inside the iOS Simulator

    iOS 模拟器不支持电话呼叫;相反,在尝试拨打电话时,将会看到警报对话框:

    The alert dialog when trying to place a call

Visual Studio 演练

本演练介绍如何创建一个名为 Phoneword 的应用程序,它将字母数字电话号码转换为数字电话号码。

注意

本演练在 Windows 10 虚拟机上使用 Visual Studio Enterprise 2017。 你的设置可以与此不同,只要满足以上要求即可,但是请注意,一些屏幕截图可能因你的设置而异。

注意

继续此演练前,必须已从 Visual Studio 连接到 Mac。 这是因为 Xamarin.iOS 依赖于 Apple 的工具生成并启动应用程序。 若要获取设置,请执行与 Mac 配对指南中的步骤。

  1. 从“开始”菜单启动 Visual Studio:

    The Start screen

    通过选择“文件>新建>项目...”创建新的 Xamarin.iOS 解决方案... >Visual C# > i电话 & iPad > iOS 应用(Xamarin)

    Select iOS App (Xamarin) project type

    在接下来出现的对话框中,选择“单视图应用”模板,然后按“确定”创建项目

    Select Single View project template

  2. 确认工具栏中的 Xamarin Mac 代理图标为绿色。

    Confirm that the Xamarin Mac Agent icon in the toolbar is green

    如果不是,则意味着没有连接到 Mac 生成主机,请按照配置指南中的步骤进行连接。

  3. 通过在“解决方案资源管理器”中双击 iOS 设计器中的 Main.storyboard 文件来打开它:

    The iOS Designer

  4. 打开“工具箱”选项卡,向搜索栏中输入“标签”并将一个“标签”拖动到设计图面上(中央区域):

    Drag a Label onto the design surface the area in the center

  5. 接下来,抓取“拖动控件”的图柄,并拉宽标签:

    Make the label wider

  6. 在设计图面上选择了“标签”的情况下,使用“属性窗口”将“标签”的“文本”属性更改为“Enter a Phoneword:”

    Change the Text property of the Label to Enter a Phoneword

    注意

    可以通过导航到“视图”菜单,随时打开“属性”或“工具箱”

  7. 在工具箱内搜索“文本字段”,将一个“文本字段”从“工具箱”拖动到设计图面上,并将它放置在“标签”下方。 调整宽度,直到“文本字段”的宽度与“标签”相同:

    Adjust the width until the Text Field is the same width as the Label

  8. 在设计图面上选择了“文本字段”的情况下,在“属性”的“标识”部分中将“文本字段”的“名称”属性更改为 PhoneNumberText,并将“文本”属性更改为“1-855-XAMARIN”:

    Change the Text property to 1-855-XAMARIN

  9. 将一个“按钮”从“工具箱”拖动到设计图面上,并将它放置在“文本字段”下方。 调整宽度,以便“按钮”与“文本字段”和“标签”一样宽:

    Adjust the width so the Button is as wide as the Text Field and Label

  10. 在设计图面上选择了“按钮”的情况下,在“属性”的“标识”部分中将“名称”属性更改为 TranslateButton。 将“标题”属性更改为“Translate”:

    Change the Title property to Translate

  11. 重复前面的两个步骤,将一个“按钮”从“工具箱”拖动到设计图面上,并将它放置第一个“按钮”下方。 调整宽度,以便该“按钮”与第一个“按钮”一样宽:

    Adjust the width so the Button is as wide as the first Button

  12. 在设计图面上选择了第二个“按钮”的情况下,在“属性”的“标识”部分中将“名称”属性更改为 CallButton。 将“标题”属性更改为“Call”:

    Change the Title property to Call

    通过导航到“全部文件>保存”或按 Ctrl + s 保存更改。

  13. 添加一些代码,以将电话号码从字母数字转换为数字。 为此,请先在解决方案资源管理器中右键单击电话word 项目,然后选择“添加新>项...”或按 Ctrl + Shift + A 向项目添加新文件:

    Add some code to translate phone numbers from alphanumeric to numeric

  14. “添加新项 ”对话框中(右键单击项目,选择“添加新 > 项...”),选择 Apple > 类 并命名新文件 PhoneTranslator

    Add a new class named PhoneTranslator

    重要

    请确保选择在图标中包含 C# 的“类”模板。 否则,可能无法引用此新类。

  15. 这会创建新 C# 类。 删除所有模板代码并替换为以下代码:

    using System.Text;
    using System;
    
    namespace Phoneword
    {
        public static class PhoneTranslator
        {
            public static string ToNumber(string raw)
            {
                if (string.IsNullOrWhiteSpace(raw)) {
                    return "";
                } else {
                    raw = raw.ToUpperInvariant();
                }
    
                var newNumber = new StringBuilder();
                foreach (var c in raw)
                {
                    if (" -0123456789".Contains(c)) {
                        newNumber.Append(c);
                    } else {
                        var result = TranslateToNumber(c);
                        if (result != null) {
                            newNumber.Append(result);
                        }
                    }
                    // otherwise we've skipped a non-numeric char
                }
                return newNumber.ToString();
            }
    
            static bool Contains (this string keyString, char c)
            {
                return keyString.IndexOf(c) >= 0;
            }
    
            static int? TranslateToNumber(char c)
            {
                if ("ABC".Contains(c)) {
                    return 2;
                } else if ("DEF".Contains(c)) {
                    return 3;
                } else if ("GHI".Contains(c)) {
                    return 4;
                } else if ("JKL".Contains(c)) {
                    return 5;
                } else if ("MNO".Contains(c)) {
                    return 6;
                } else if ("PQRS".Contains(c)) {
                    return 7;
                } else if ("TUV".Contains(c)) {
                    return 8;
                } else if ("WXYZ".Contains(c)) {
                    return 9;
                }
                return null;
            }
        }
    }
    

    保存 PhoneTranslator.cs 文件并关闭它。

  16. 在“解决方案资源管理器”中双击 ViewController.cs 以打开它,以便可以添加逻辑以处于与按钮进行的交互:

    Logic added to handle interactions with the buttons

  17. 首先关联 TranslateButton。 在 ViewController 类中,找到 ViewDidLoad 方法。 在 ViewDidLoad 中的 base.ViewDidLoad() 调用下添加以下按钮代码:

    string translatedNumber = "";
    
    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;
            }
    };
    

    如果文件的命名空间不同,则包括 using Phoneword;

  18. 添加代码以响应按第二个按钮的用户(名为 CallButton)。 将以下代码置于 TranslateButton 的代码下方,并将 using Foundation; 添加到文件顶部:

    CallButton.TouchUpInside += (object sender, EventArgs e) => {
        var url = new NSUrl ("tel:" + translatedNumber);
    
            // Use URL handler with tel: prefix to invoke Apple's Phone app,
            // 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);
                    }
    };
    
  19. 保存更改,然后选择“生成>生成解决方案或按 Ctrl + Shift + B 生成应用程序。如果应用程序编译,IDE 底部会显示一条成功消息:

    A success message will appear at the bottom of the IDE

    如果发生错误,则完成前面的步骤并更正任何错误,直到应用程序成功生成。

  20. 最后,在“远程 iOS 模拟器”中测试应用程序。 在 IDE 工具栏中,从下拉菜单中选择“调试”和“iPhone 8 Plus iOS x.x”,然后按“启动”(类似于“播放”按钮的绿色三角形):

    Press Start

  21. 这会在 iOS 模拟器中启动应用程序:

    The application running inside the iOS Simulator

    iOS 模拟器不支持电话呼叫;相反,在尝试拨打电话时,将会看到警报对话框:

    An alert dialog will display when trying to place a call

祝贺你完成第一个 Xamarin.iOS 应用程序!

现在,可以剖析 Hello,iOS 深入了解的本指南中显示的工具和技能。