在 Xamarin 中使用 tvOS 警报

本文介绍如何使用 UIAlertController 在 Xamarin.tvOS 中向用户显示警报消息

如果你需要引起 tvOS 用户的注意或请求执行破坏性操作(例如删除文件)的权限,可以使用 UIAlertViewController 显示警报消息:

UIAlertViewController 示例

除了显示消息之外,还可以向警报添加按钮和文本字段,以允许用户响应操作并提供反馈。

关于警报

如上所述,警报用于引起用户注意并告知他们应用的状态或请求反馈。 警报必须显示一个标题,可以选择包含一条消息以及一个或多个按钮或文本字段。

示例警报

Apple 在使用警报方面提出了以下建议:

  • 谨慎使用警报 - 警报会扰乱用户使用应用的流程并中断用户体验,因此只应在重要情况下使用警报,例如错误通知、应用内购买和破坏性操作
  • 提供有用的选项 - 如果警报向用户提供选项,应确保每个选项都提供了关键信息并为用户提供有用的操作

警报标题和消息

Apple 在显示警报标题和可选消息方面提出了以下建议:

  • 使用多字词标题 - 警报标题应清楚地表达情景要点,同时保持简单。 单字词标题极少能够提供足够的信息。
  • 使用不需要消息的描述性标题 - 在可能的情况下,请考虑使警报标题具有足够的描述性,以便不需要可选的消息文本
  • 以简短、完整的句子编写消息 - 如果需要通过可选消息来表达警报要点,请使其尽可能简单,并以正确大小写和标点符号编写完整的句子

警报按钮

Apple 在向警报添加按钮方面提出了以下建议:

  • 限制为两个按钮 - 尽可能将警报限制为最多两个按钮。 单按钮警报提供信息,但不提供任何操作。 双按钮警报提供简单的“是/否”选择操作。
  • 使用简洁、逻辑性强的按钮标题 - 简单的一到两个字词的按钮标题可以清楚地描述按钮的操作效果。 有关详细信息,请参阅使用按钮文档。
  • 清楚地标记破坏性按钮 - 对于执行破坏性操作(例如删除文件)的按钮,请使用 UIAlertActionStyle.Destructive 样式来清楚地标记它们。

显示警报

若要显示警报,可以创建 UIAlertViewController 的实例,并通过添加操作(按钮)和选择警报样式来配置它。 例如,以下代码显示“确定/取消”警报:

const string title = "A Short Title is Best";
const string message = "A message should be a short, complete sentence.";
const string acceptButtonTitle = "OK";
const string cancelButtonTitle = "Cancel";
const string deleteButtonTitle = "Delete";
...

var alertController = UIAlertController.Create (title, message, UIAlertControllerStyle.Alert);

// Create the action.
var acceptAction = UIAlertAction.Create (acceptButtonTitle, UIAlertActionStyle.Default, _ =>
    Console.WriteLine ("The \"OK/Cancel\" alert's other action occurred.")
);

var cancelAction = UIAlertAction.Create (cancelButtonTitle, UIAlertActionStyle.Cancel, _ =>
    Console.WriteLine ("The \"OK/Cancel\" alert's other action occurred.")
);

// Add the actions.
alertController.AddAction (acceptAction);
alertController.AddAction (cancelAction);
PresentViewController (alertController, true, null);

让我们详细分析这段代码。 首先,我们创建一个具有给定标题和消息的新警报:

UIAlertController.Create (title, message, UIAlertControllerStyle.Alert)

接下来,对于要在警报中显示的每个按钮,我们创建一个操作,用于定义按钮的标题、样式以及按下按钮时要执行的操作:

UIAlertAction.Create ("Button Title", UIAlertActionStyle.Default, _ =>
    // Do something when the button is pressed
    ...
);

UIAlertActionStyle 枚举允许将按钮的样式设置为下列其中一项:

  • 默认 - 该按钮将是显示警报时选择的默认按钮
  • 取消 - 该按钮是警报的取消按钮
  • 破坏性 - 将该按钮突出显示为破坏性操作,例如删除文件。 目前,tvOS 将“破坏性”按钮呈现为红色背景。

AddAction 方法将给定的操作添加到 UIAlertViewController,最后 PresentViewController (alertController, true, null) 方法向用户显示给定的警报。

添加文本字段

除了向警报添加操作(按钮)之外,还可以向警报添加文本字段,以允许用户填写用户 ID 和密码等信息:

警报中的文本字段

如果用户选择“文本字段”,将显示标准 tvOS 键盘,使他们能够输入该字段的值:

输入文本

以下代码显示“确定/取消”警报,其中包含用于输入值的单个文本字段:

UIAlertController alert = UIAlertController.Create(title, description, UIAlertControllerStyle.Alert);
UITextField field = null;

// Add and configure text field
alert.AddTextField ((textField) => {
    // Save the field
    field = textField;

    // Initialize field
    field.Placeholder = placeholder;
    field.Text = text;
    field.AutocorrectionType = UITextAutocorrectionType.No;
    field.KeyboardType = UIKeyboardType.Default;
    field.ReturnKeyType = UIReturnKeyType.Done;
    field.ClearButtonMode = UITextFieldViewMode.WhileEditing;

});

// Add cancel button
alert.AddAction(UIAlertAction.Create("Cancel",UIAlertActionStyle.Cancel,(actionCancel) => {
    // User canceled, do something
    ...
}));

// Add ok button
alert.AddAction(UIAlertAction.Create("OK",UIAlertActionStyle.Default,(actionOK) => {
    // User selected ok, do something
    ...
}));

// Display the alert
controller.PresentViewController(alert,true,null);

AddTextField 方法向警报添加一个新的文本字段,然后你可以通过设置占位符文本(字段为空时显示的文本)、默认文本值和键盘类型等属性来配置该文本字段。 例如:

// Initialize field
field.Placeholder = placeholder;
field.Text = text;
field.AutocorrectionType = UITextAutocorrectionType.No;
field.KeyboardType = UIKeyboardType.Default;
field.ReturnKeyType = UIReturnKeyType.Done;
field.ClearButtonMode = UITextFieldViewMode.WhileEditing;

为了稍后可以对文本字段的值进行操作,我们还使用以下代码保存了一个副本:

UITextField field = null;
...

// Add and configure text field
alert.AddTextField ((textField) => {
    // Save the field
    field = textField;
    ...
});

用户在文本字段中输入值后,我们可以使用 field 变量来访问该值。

警报视图控制器帮助器类

由于使用 UIAlertViewController 显示简单、常见类型的警报可能会导致大量重复代码,因此可以使用帮助器类来减少重复代码量。 例如:

using System;
using Foundation;
using UIKit;
using System.CodeDom.Compiler;

namespace UIKit
{
    /// <summary>
    /// Alert view controller is a reusable helper class that makes working with <c>UIAlertViewController</c> alerts
    /// easier in a tvOS app.
    /// </summary>
    public class AlertViewController
    {
        #region Static Methods
        public static UIAlertController PresentOKAlert(string title, string description, UIViewController controller) {
            // No, inform the user that they must create a home first
            UIAlertController alert = UIAlertController.Create(title, description, UIAlertControllerStyle.Alert);

            // Configure the alert
            alert.AddAction(UIAlertAction.Create("OK",UIAlertActionStyle.Default,(action) => {}));

            // Display the alert
            controller.PresentViewController(alert,true,null);

            // Return created controller
            return alert;
        }

        public static UIAlertController PresentOKCancelAlert(string title, string description, UIViewController controller, AlertOKCancelDelegate action) {
            // No, inform the user that they must create a home first
            UIAlertController alert = UIAlertController.Create(title, description, UIAlertControllerStyle.Alert);

            // Add cancel button
            alert.AddAction(UIAlertAction.Create("Cancel",UIAlertActionStyle.Cancel,(actionCancel) => {
                // Any action?
                if (action!=null) {
                    action(false);
                }
            }));

            // Add ok button
            alert.AddAction(UIAlertAction.Create("OK",UIAlertActionStyle.Default,(actionOK) => {
                // Any action?
                if (action!=null) {
                    action(true);
                }
            }));

            // Display the alert
            controller.PresentViewController(alert,true,null);

            // Return created controller
            return alert;
        }

        public static UIAlertController PresentDestructiveAlert(string title, string description, string destructiveAction, UIViewController controller, AlertOKCancelDelegate action) {
            // No, inform the user that they must create a home first
            UIAlertController alert = UIAlertController.Create(title, description, UIAlertControllerStyle.Alert);

            // Add cancel button
            alert.AddAction(UIAlertAction.Create("Cancel",UIAlertActionStyle.Cancel,(actionCancel) => {
                // Any action?
                if (action!=null) {
                    action(false);
                }
            }));

            // Add ok button
            alert.AddAction(UIAlertAction.Create(destructiveAction,UIAlertActionStyle.Destructive,(actionOK) => {
                // Any action?
                if (action!=null) {
                    action(true);
                }
            }));

            // Display the alert
            controller.PresentViewController(alert,true,null);

            // Return created controller
            return alert;
        }

        public static UIAlertController PresentTextInputAlert(string title, string description, string placeholder, string text, UIViewController controller, AlertTextInputDelegate action) {
            // No, inform the user that they must create a home first
            UIAlertController alert = UIAlertController.Create(title, description, UIAlertControllerStyle.Alert);
            UITextField field = null;

            // Add and configure text field
            alert.AddTextField ((textField) => {
                // Save the field
                field = textField;

                // Initialize field
                field.Placeholder = placeholder;
                field.Text = text;
                field.AutocorrectionType = UITextAutocorrectionType.No;
                field.KeyboardType = UIKeyboardType.Default;
                field.ReturnKeyType = UIReturnKeyType.Done;
                field.ClearButtonMode = UITextFieldViewMode.WhileEditing;

            });

            // Add cancel button
            alert.AddAction(UIAlertAction.Create("Cancel",UIAlertActionStyle.Cancel,(actionCancel) => {
                // Any action?
                if (action!=null) {
                    action(false,"");
                }
            }));

            // Add ok button
            alert.AddAction(UIAlertAction.Create("OK",UIAlertActionStyle.Default,(actionOK) => {
                // Any action?
                if (action!=null && field !=null) {
                    action(true, field.Text);
                }
            }));

            // Display the alert
            controller.PresentViewController(alert,true,null);

            // Return created controller
            return alert;
        }
        #endregion

        #region Delegates
        public delegate void AlertOKCancelDelegate(bool OK);
        public delegate void AlertTextInputDelegate(bool OK, string text);
        #endregion
    }
}

使用此类,可以如下所示显示和响应简单警报:

#region Custom Actions
partial void DisplayDestructiveAlert (Foundation.NSObject sender) {
    // User helper class to present alert
    AlertViewController.PresentDestructiveAlert("A Short Title is Best","The message should be a short, complete sentence.","Delete",this, (ok) => {
        Console.WriteLine("Destructive Alert: The user selected {0}",ok);
    });
}

partial void DisplayOkCancelAlert (Foundation.NSObject sender) {
    // User helper class to present alert
    AlertViewController.PresentOKCancelAlert("A Short Title is Best","The message should be a short, complete sentence.",this, (ok) => {
        Console.WriteLine("OK/Cancel Alert: The user selected {0}",ok);
    });
}

partial void DisplaySimpleAlert (Foundation.NSObject sender) {
    // User helper class to present alert
    AlertViewController.PresentOKAlert("A Short Title is Best","The message should be a short, complete sentence.",this);
}

partial void DisplayTextInputAlert (Foundation.NSObject sender) {
    // User helper class to present alert
    AlertViewController.PresentTextInputAlert("A Short Title is Best","The message should be a short, complete sentence.","placeholder", "", this, (ok, text) => {
        Console.WriteLine("Text Input Alert: The user selected {0} and entered `{1}`",ok,text);
    });
}
#endregion

总结

本文已介绍如何在 Xamarin.tvOS 中使用 UIAlertController 向用户显示警报消息。 首先,介绍了如何显示简单的警报和添加按钮。 接下来,介绍了如何将文本字段添加到警报。 最后,演示了如何使用帮助器类来减少显示警报所需的重复代码量。