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 设计用户界面

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

Hello.iOS 快速入门应用

要求

使用 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

    “启动”屏幕

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

    iOS 解决方案

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

    选择“单一视图应用程序”

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

    输入应用名称

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

    选择项目的位置

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

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

    iOS 设计器

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

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

    将“标签”拖动到中心区域的设计图面上

    注意

    可以通过导航到“视图”>“面板”,随时打开“Properties Pad”或“工具箱”

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

    增加标签宽度

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

    将标签设为“输入 Phoneword”

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

    将“文本字段”宽度设置为与“标签”相同

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

    将“标题”属性更改为“1-855-XAMARIN”

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

    调整宽度以便“按钮”的宽度与“文本字段”和“标签”相同

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

    将“标题”属性更改为“Translate”

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

    调整宽度,使该按钮宽度与第一个按钮相同

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

    将“标题”属性更改为“Call”

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

  16. 需要将一些逻辑添加到应用,以便将电话号码为字母数字转换为数字。 右键单击“Solution Pad”中的“Phoneword_iOS”,再依次选择“添加”>“新建文件…”或按“⌘ + n”,向项目添加新文件

    向项目添加一个新文件

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

    选择 Empty 类,将新的文件命名为“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以打开它:

    添加代码,关联用户界面

  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 顶部:

    成功消息将出现在 IDE 顶部

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

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

    选择模拟器,然后按“启动”

    注意

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

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

    应用程序在 iOS 模拟器中运行

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

    尝试拨打电话时的警报对话框

Visual Studio 演练

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

注意

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

注意

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

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

    “启动”屏幕

    通过选择“文件”>“新建”>“项目...”>“Visual C#”>“iPhone 和 iPad”>“iOS 应用(Xamarin)”,创建新的 Xamarin.iOS 解决方案:

    选择“iOS 应用 (Xamarin)”项目类型

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

    选择“单一视图”项目模版

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

    确认工具栏中的 Xamarin Mac Agent 图标是否为绿色

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

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

    iOS 设计器

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

    将“标签”拖动到中心区域的设计图面上

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

    增加标签宽度

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

    将“标签”的“文本”属性更改为“Enter a Phoneword”

    注意

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

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

    调整宽度以便“文本字段”的宽度与“标签”相同

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

    将“文本”属性更改为“1-855-XAMARIN”

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

    调整宽度以便“按钮”的宽度与“文本字段”和“标签”相同

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

    将“标题”属性更改为“Translate”

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

    调整宽度,使该按钮宽度与第一个按钮相同

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

    将“标题”属性更改为“Call”

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

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

    添加一些代码以将电话号码从字母数字转换为数字

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

    添加名为“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 以打开它,以便可以添加逻辑以处于与按钮进行的交互:

    添加逻辑以处理与按钮之间的交互

  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 底部:

    成功消息将出现在 IDE 底部

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

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

    按“启动”

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

    应用程序在 iOS 模拟器中运行

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

    尝试拨打电话时会显示警报对话框

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

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