Кнопки действия динамического уведомления в Xamarin.iOS
В iOS 12 уведомления могут динамически добавлять, удалять и обновлять связанные с ними кнопки действий. Такая настройка позволяет предоставить пользователям действия, непосредственно относящиеся к содержимому уведомления и взаимодействию пользователя с ним.
Пример приложения: RedGreenNotifications
Фрагменты кода в этом руководстве поступают из примера приложения, в котором показано, как использовать Xamarin.iOS для работы с кнопками действий уведомлений в iOS 12.
В этом примере приложения отправляются два типа локальных уведомлений: красный и зеленый. После отправки уведомления используйте 3D Touch для просмотра пользовательского пользовательского интерфейса. Затем используйте кнопки действий уведомления для поворота отображаемого изображения. По мере поворота изображения появится кнопка "Сброс поворота " и исчезает по мере необходимости.
Фрагменты кода в этом руководстве поступают из этого примера приложения.
Кнопки действий по умолчанию
Категория уведомления определяет кнопки действий по умолчанию.
Создание и регистрация категорий уведомлений во время запуска приложения.
Например, в примере приложенияFinishedLaunching
метод AppDelegate
выполняет следующее:
- Определяет одну категорию красных уведомлений и другую для зеленых уведомлений
- Регистрирует эти категории путем вызова
SetNotificationCategories
методUNUserNotificationCenter
- Присоединение одного
UNNotificationAction
для каждой категории
В следующем примере кода показано, как это работает:
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// Request authorization to send notifications
UNUserNotificationCenter center = UNUserNotificationCenter.Current;
var options = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Provisional | UNAuthorizationOptions.ProvidesAppNotificationSettings;
center.RequestAuthorization(options, (bool success, NSError error) =>
{
// ...
var rotateTwentyDegreesAction = UNNotificationAction.FromIdentifier("rotate-twenty-degrees-action", "Rotate 20°", UNNotificationActionOptions.None);
var redCategory = UNNotificationCategory.FromIdentifier(
"red-category",
new UNNotificationAction[] { rotateTwentyDegreesAction },
new string[] { },
UNNotificationCategoryOptions.CustomDismissAction
);
var greenCategory = UNNotificationCategory.FromIdentifier(
"green-category",
new UNNotificationAction[] { rotateTwentyDegreesAction },
new string[] { },
UNNotificationCategoryOptions.CustomDismissAction
);
var set = new NSSet<UNNotificationCategory>(redCategory, greenCategory);
center.SetNotificationCategories(set);
});
// ...
}
На основе этого кода все уведомления, чьи уведомления Content.CategoryIdentifier
Имеет значение "красная категория" или "зеленая категория", по умолчанию отображается кнопка "Повернуть 20 градусов".
Обработка кнопок действия уведомлений в приложении
UNUserNotificationCenter
Delegate
имеет свойство типаIUNUserNotificationCenterDelegate
.
В примере приложения AppDelegate
задает себя в качестве делегата центра уведомлений пользователя в FinishedLaunching
:
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// Request authorization to send notifications
UNUserNotificationCenter center = UNUserNotificationCenter.Current;
var options = // ...
center.RequestAuthorization(options, (bool success, NSError error) =>
{
center.Delegate = this;
// ...
AppDelegate
Затем реализуетDidReceiveNotificationResponse
Для обработки нажатий кнопки действия:
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, System.Action completionHandler)
{
if (response.IsDefaultAction)
{
Console.WriteLine("ACTION: Default");
}
if (response.IsDismissAction)
{
Console.WriteLine("ACTION: Dismiss");
}
else
{
Console.WriteLine($"ACTION: {response.ActionIdentifier}");
}
completionHandler();
}
Эта реализация DidReceiveNotificationResponse
не обрабатывает кнопку действия поворота уведомления 20° . Вместо этого расширение содержимого уведомления обрабатывает касания этой кнопки. В следующем разделе описана обработка кнопки уведомлений.
Кнопки действий в расширении содержимого уведомлений
Расширение содержимого уведомления содержит контроллер представления, определяющий пользовательский интерфейс для уведомления.
Этот контроллер представления может использовать GetNotificationActions
методы и SetNotificationActions
методы для его ExtensionContext
свойство для доступа и изменения кнопок действия уведомления.
В примере приложения контроллер представления содержимого уведомления изменяет кнопки действий только при ответе на касание уже существующей кнопки действия.
Примечание.
Расширение содержимого уведомления может реагировать на нажатие кнопки действия в методе контроллера DidReceiveNotificationResponse
представления, объявленном как часть IUNNotificationContentExtension.
Хотя он использует имя с методом DidReceiveNotificationResponse
, описанным выше, это другой метод.
После завершения обработки касания кнопки расширение содержимого уведомления может выбрать, следует ли сообщить основному приложению обработать это же нажатие кнопки. Для этого необходимо передать соответствующее значение UNNotificationContentExtensionResponseOption в обработчик завершения:
Dismiss
указывает, что интерфейс уведомлений должен быть закрыт, и что главное приложение не должно обрабатывать касание кнопки.DismissAndForwardAction
указывает, что интерфейс уведомлений должен быть закрыт, и что основное приложение также должно обрабатывать касание кнопки.DoNotDismiss
указывает, что интерфейс уведомлений не должен быть закрыт, и что главное приложение не должно обрабатывать нажатие кнопки.
Метод расширения DidReceiveNotificationResponse
содержимого определяет, какая кнопка действия была набита, поворачивает изображение в интерфейсе уведомления и отображает или скрывает кнопку действия сброса:
[Export("didReceiveNotificationResponse:completionHandler:")]
public void DidReceiveNotificationResponse(UNNotificationResponse response, Action<UNNotificationContentExtensionResponseOption> completionHandler)
{
var rotationAction = ExtensionContext.GetNotificationActions()[0];
if (response.ActionIdentifier == "rotate-twenty-degrees-action")
{
rotationButtonTaps += 1;
double radians = (20 * rotationButtonTaps) * (2 * Math.PI / 360.0);
Xamagon.Transform = CGAffineTransform.MakeRotation((float)radians);
// 9 rotations * 20 degrees = 180 degrees. No reason to
// show the reset rotation button when the image is half
// or fully rotated.
if (rotationButtonTaps % 9 == 0)
{
ExtensionContext.SetNotificationActions(new UNNotificationAction[] { rotationAction });
}
else if (rotationButtonTaps % 9 == 1)
{
var resetRotationAction = UNNotificationAction.FromIdentifier("reset-rotation-action", "Reset rotation", UNNotificationActionOptions.None);
ExtensionContext.SetNotificationActions(new UNNotificationAction[] { rotationAction, resetRotationAction });
}
}
if (response.ActionIdentifier == "reset-rotation-action")
{
rotationButtonTaps = 0;
double radians = (20 * rotationButtonTaps) * (2 * Math.PI / 360.0);
Xamagon.Transform = CGAffineTransform.MakeRotation((float)radians);
ExtensionContext.SetNotificationActions(new UNNotificationAction[] { rotationAction });
}
completionHandler(UNNotificationContentExtensionResponseOption.DoNotDismiss);
}
В этом случае метод передается UNNotificationContentExtensionResponseOption.DoNotDismiss
обработчику завершения. Это означает, что интерфейс уведомления останется открытым.