使用 JSON 在 Xamarin.iOS 中创建用户界面

MonoTouch.Dialog (MT.D) 支持通过 JSON 数据生成动态 UI。 本教程将介绍如何使用 JSONElement 从应用程序随附的 JSON 或从远程 URL 加载的 JSON 创建用户界面。

MT.D 支持创建 JSON 中声明的用户界面。 使用 JSON 声明元素时,MT.D 将自动为你创建关联的元素。 可以从本地文件、已分析的 JsonObject 实例,甚至远程 URL 加载 JSON。

MT.D 支持使用 JSON 时元素 API 中提供的全部功能。 例如,以下屏幕截图中的应用程序完全使用 JSON 声明:

例如,此屏幕截图中的应用程序完全使用 JSON 声明:例如,此屏幕截图中的应用程序完全使用 JSON 声明:

让我们回顾一下元素 API 演练教程中的示例,其中展示了如何使用 JSON 添加任务详细信息屏幕。

设置 MT.D

MT.D 与 Xamarin.iOS 一起分发。 若要使用它,请右键单击 Visual Studio 2017 或 Visual Studio for Mac 中 Xamarin.iOS 项目的“引用”节点,然后添加对“MonoTouch.Dialog-1”程序集的引用。 然后,根据需要在源代码中添加 using MonoTouch.Dialog 语句。

JSON 演练

此演练的示例允许创建任务。 在第一个屏幕上选择任务时,将显示详细信息屏幕,如下所示:

在第一个屏幕上选择任务时,将显示详细信息屏幕,如下所示

创建 JSON

在此示例中,将从名为 task.json 的项目中的文件加载 JSON。 MT.D 要求 JSON 符合反映元素 API 的语法。 就像在代码中使用元素 API 一样,使用 JSON 时,我们声明部分,并在这些部分中添加元素。 若要在 JSON 中声明部分和元素,我们分别使用字符串“sections”和“elements”作为键。 对于每个元素,将使用 type 键设置关联的元素类型。 所有其他元素属性均以属性名称作为键进行设置。

例如,以下 JSON 描述了任务详细信息的部分和元素:

{
    "title": "Task",
    "sections": [
        {
            "elements" : [
                {
                    "id" : "task-description",
                    "type": "entry",
                    "placeholder": "Enter task description"
                },
                {
                    "id" : "task-duedate",
                    "type": "date",
                    "caption": "Due Date",
                    "value": "00:00"
                }
            ]
        }
    ]
}

请注意,上述 JSON 包含每个元素的 ID。 任何元素都可以包含 ID,以便在运行时引用。 在展示如何在代码中加载 JSON 时,我们将看到如何使用此 ID。

在代码中加载 JSON

定义 JSON 后,需要使用 JsonElement 类将其加载到 MT.D 中。 假设上面创建的 JSON 文件已添加到名为 example.json 的项目中,并给出了内容的生成操作,则加载 JsonElement 就像调用以下代码行一样简单:

var taskElement = JsonElement.FromFile ("task.json");

由于每次创建任务时都会按需添加此内容,因此可以修改在前面元素 API 示例中单击的按钮,如下所示:

_addButton.Clicked += (sender, e) => {
    ++n;

    var task = new Task{Name = "task " + n, DueDate = DateTime.Now};

    var taskElement = JsonElement.FromFile ("task.json");

    _rootElement [0].Add (taskElement);
};

在运行时访问元素

回想一下,我们在 JSON 文件中声明了两个元素时,为其添加了 ID。 可以使用 ID 属性在运行时访问每个元素,以在代码中修改其属性。 例如,以下代码引用条目和日期元素来设置任务对象中的值:

_addButton.Clicked += (sender, e) => {
    ++n;

    var task = new Task{Name = "task " + n, DueDate = DateTime.Now};

    var taskElement = JsonElement.FromFile ("task.json");

    taskElement.Caption = task.Name;

    var description = taskElement ["task-description"] as EntryElement;

    if (description != null) {
        description.Caption = task.Name;
        description.Value = task.Description;       
    }

    var duedate = taskElement ["task-duedate"] as DateElement;

    if (duedate != null) {                
        duedate.DateValue = task.DueDate;
    }
    _rootElement [0].Add (taskElement);
};

从 URL 加载 JSON

MT.D 还支持从外部 URL 动态加载 JSON,只需将 URL 传递给 JsonElement 的构造函数即可。 在屏幕之间导航时,MT.D 将按需扩展 JSON 中声明的层次结构。 例如,以一个位于本地 Web 服务器根目录的 JSON 文件为例,如下所示:

{
    "type": "root",
    "title": "home",
    "sections": [
        {
            "header": "Nested view!",
            "elements": [
                {
                    "type": "boolean",
                    "caption": "Just a boolean",
                    "id": "first-boolean",
                    "value": false
                },
                {
                    "type": "string",
                    "caption": "Welcome to the nested controller"
                }
            ]
        }
    ]
}

可以使用 JsonElement 加载此文件,如以下代码所示:

_rootElement = new RootElement ("Json Example") {
    new Section ("") {
        new JsonElement ("Load from url", "http://localhost/sample.json")
    }
};

在运行时,当用户导航到第二个视图时,MT.D 将检索并分析该文件,如以下屏幕截图所示:

当用户导航到第二个视图时,文件将由 MT.D 检索和分析

总结

本文介绍了如何通过 JSON 创建使用 MT.D 的界面。 文中展示了如何使用应用程序以及从远程 URL 中加载文件包含的 JSON。 文中还展示了如何在运行时访问 JSON 中描述的元素。