Правильно представить UIAlertController от MSMessagesAppViewController
Я пытаюсь выяснить, как отобразить UIAlertController
со стилем UIAlertControllerStyleActionSheet
в моем расширении приложения iMessage.
Проблема в том, что лист действий появляется под собственным текстовым полем iMessage, когда отображается при вызове:
[self.view.window.rootViewController presentViewController:actionSheetController animated:YES completion:NULL];
Как мне исправить это?
Код:
UIAlertController *actionSheetController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Clear", nil) message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *clear = [UIAlertAction actionWithTitle:NSLocalizedString(@"Clear", nil) style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action)
{
[self clear];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action)
{}];
[actionSheetController addAction:clear];
[actionSheetController addAction:cancel];
[self.view.window.rootViewController presentViewController:actionSheetController animated:YES completion:NULL];
4 ответа
Вот обходной путь. Может быть, добавить немного анимации, чтобы сделать его гладким.
[self.view.window.rootViewController presentViewController:actionSheetController animated:YES completion:^{
actionSheetController.view.frame = CGRectOffset(actionSheetController.view.frame, 0, -40);
}];
Другой обходной путь:
actionSheetController.view.transform = CGAffineTransform(translationX: 0, y: -40)
[self.view.window.rootViewController presentViewController:actionSheetController animated:YES completion:NULL];
Не жестко кодируйте y-позицию для листа действий.
Это может привести к проблемам с пользовательским интерфейсом в более поздних основных обновлениях iOS, когда яблоко меняет высоту дока iMessage. Вместо этого используйте safeAreaInsets.bottom
значение, чтобы узнать, по какому значению вид скрывается доком.
Вот решение, которое мы используем:
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (_) in
actionSheet.dismiss(animated: true, completion: nil)
}))
// Adding further actions...
present(actionSheet, animated: true) {
UIView.animate(withDuration: 0.2, animations: {
actionSheet.view.frame = CGRect(x: actionSheet.view.frame.minX,
y: actionSheet.view.frame.minY - self.view.safeAreaInsets.bottom,
width: actionSheet.view.frame.width,
height: actionSheet.view.frame.height)
})
}
Подробно: лист действий скрыт док-станцией iMessage, потому что представление контроллеров представления, над которым вы представляете лист действий, привязано к нижней части вида, а не к верхней части док-станции iMessage. Этот случай должен быть рассмотрен, например, при добавлении ограничений к другим представлениям и их подпредставлениям.
Обновить:
Просто используйте следующий код, чтобы избежать анимации выше. В моем случае, после того, как я увидел время, анимация стала довольно раздражающей.
extension UIAlertController {
open override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let viewController = presentingViewController else { return }
view.transform = .identity
view.transform = .init(translationX: 0.0, y: - viewController.view.safeAreaInsets.bottom)
}
}
В соответствии с этим вы можете запросить полноэкранное представление по:
[self requestPresentationStyle:MSMessagesAppPresentationStyleExpanded];
перед вашим кодом:
[self.view.window.rootViewController presentViewController:actionSheetController animated:YES completion:NULL];