Properly Present a UIAlertController from MSMessagesAppViewController

◇◆丶佛笑我妖孽 提交于 2019-12-19 12:52:10

问题


I'm trying to figure out how to display a UIAlertController with a style of UIAlertControllerStyleActionSheet within my iMessage app extension.

The problem is, the action sheet appears below the native iMessage text field when presented when calling:

[self.view.window.rootViewController presentViewController:actionSheetController animated:YES completion:NULL];

How would I go about fixing this?

Code:

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];


回答1:


Here is a workaround. Maybe add a little animation to make it smooth.

[self.view.window.rootViewController presentViewController:actionSheetController animated:YES completion:^{
    actionSheetController.view.frame = CGRectOffset(actionSheetController.view.frame, 0, -40);
}];



回答2:


Another workaround:

actionSheetController.view.transform = CGAffineTransform(translationX: 0, y: -40)    
[self.view.window.rootViewController presentViewController:actionSheetController animated:YES completion:NULL];



回答3:


Do not hardcode the y-position for the action sheet.

This could lead to ui issues on later iOS major updates, when apple changes the height of the iMessage dock. Instead use the safeAreaInsets.bottom value in order to find out by which value the view is hidden by the dock.

Here is the solution we are using:

    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)
        })
    }

Detail: The action sheet is hidden by the iMessage dock, because the view controllers view over which you are presenting the action sheet is tied up to the bottom of the view and not the top of the iMessage dock. This case must be considered e.g. when adding constraints to other views and its subview.


Update:

Just use the following code in order to avoid the animation above. In my case after time seeing the animation did get pretty annoying.

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)
    }
}



回答4:


according to this, you can request full screen presentation by:

[self requestPresentationStyle:MSMessagesAppPresentationStyleExpanded];

before your code:

[self.view.window.rootViewController presentViewController:actionSheetController animated:YES completion:NULL];


来源:https://stackoverflow.com/questions/39759872/properly-present-a-uialertcontroller-from-msmessagesappviewcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!