行动 Sheet 问题 iOS 9

Action Sheet problems in iOS 9

Apple 已弃用 iOS 中的操作 sheet 8.3 如何向我的用户界面添加操作 sheet?

我意识到 Apple 的文档对于如何使用 UIAlertController 创建操作 sheet 不是很清楚。所以在玩了一会儿之后我只想分享我的代码,因为我在 Stack Exchange 上找不到关于这个主题的任何有用信息。

这是我在我的应用程序中用于操作的代码片段 sheet,以防万一有人在尝试弄清楚如何将 UIAlertController 作为操作使用时需要帮助 Sheet。

UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Action Sheet"
                                                                       message:@"This is an action sheet."
                                                                preferredStyle:UIAlertControllerStyleActionSheet];

        UIAlertAction *button1 = [UIAlertAction actionWithTitle:@"Button Title 1" style:UIAlertActionStyleDefault
                                                            handler:^(UIAlertAction * action) {
                                                                //code to run once button is pressed
                                                            }];
        UIAlertAction *button2 = [UIAlertAction actionWithTitle:@"Button Title 2" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            //code to run once button is pressed
        }];

        [alert addAction:button1];
        [alert addAction:button2];
        [self presentViewController:alert animated:YES completion:nil];

我在我的 iPhone 应用程序中遇到了同样的问题,UIActionSheet 询问用户是否要拍照,或从他们的图库中选择图像。

在 iOS9 之前,以下代码运行良好:

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
                                                         delegate:self
                                                cancelButtonTitle:@"Cancel"
                                           destructiveButtonTitle:nil
                                                otherButtonTitles:@"Take photo", @"Choose Existing", nil];
[actionSheet showInView:self.view];

然而,在iOS9中,这只是将屏幕完全变暗,什么也不会出现。

是的...谢谢 Apple。

解决方法是用 UIAlertController 替换 UIActionSheet

UIAlertController* alert = [UIAlertController
                            alertControllerWithTitle:nil      //  Must be "nil", otherwise a blank title area will appear above our two buttons
                            message:nil
                            preferredStyle:UIAlertControllerStyleActionSheet];

UIAlertAction* button0 = [UIAlertAction
                          actionWithTitle:@"Cancel"
                          style:UIAlertActionStyleCancel
                          handler:^(UIAlertAction * action)
                          {
                                //  UIAlertController will automatically dismiss the view
                          }];

UIAlertAction* button1 = [UIAlertAction
                          actionWithTitle:@"Take photo"
                          style:UIAlertActionStyleDefault
                          handler:^(UIAlertAction * action)
                          {
                              //  The user tapped on "Take a photo"
                              UIImagePickerController *imagePickerController= [[UIImagePickerController alloc] init];
                              imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
                              imagePickerController.delegate = self;
                              [self presentViewController:imagePickerController animated:YES completion:^{}];
                          }];

UIAlertAction* button2 = [UIAlertAction
                         actionWithTitle:@"Choose Existing"
                         style:UIAlertActionStyleDefault
                         handler:^(UIAlertAction * action)
                         {
                             //  The user tapped on "Choose existing"
                             UIImagePickerController *imagePickerController= [[UIImagePickerController alloc] init];
                             imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                             imagePickerController.delegate = self;
                             [self presentViewController:imagePickerController animated:YES completion:^{}];
                         }];

[alert addAction:button0];
[alert addAction:button1];
[alert addAction:button2];
[self presentViewController:alert animated:YES completion:nil];

请注意,如果您 包含取消选项(具有 UIAlertActionStyleCancel 样式的选项),那么将出现操作 sheet,但是点击操作之外的任何地方 sheet 不会 关闭菜单。

一个问题:

即使我们已经指定我们希望此 UIAlertController 具有样式 UIAlertControllerStyleActionSheet,您仍需要将标题设置为 nil,而不是空字符串,否则window.

顶部有一个丑陋的缺口

我迫不及待地想看看 perfectly-working 代码 iOS 9.2 会破解...

更新

我的评论:“但是,在iOS 9 中,所有这些所做的只是使屏幕完全变暗,并且什么也不会出现”有点错误。

实际上,我是在屏幕键盘可见的情况下打开我的 UIActionSheet。在 iOS 9 中,键盘将出现 你的 UIActionSheet 之上,所以你再也看不到你的操作 sheet (!!) ,但是您 看到屏幕的其余部分变暗了。

UIAlertController 相比,iOS 稍微多一些 user-friendly,因为它 在尝试显示操作之前隐藏 屏幕键盘 sheet 在屏幕底部。 Apple 不对 UIActionSheets 做同样事情的确切原因超出了我的范围。

(叹气。)

我现在可以回去使用 Visual Studio 吗..?

另一个更新

Apple 表示 UIActionSheets 现在 "deprecated in iOS 8"。

但是,如果您想继续使用它们,在包含文本框的 iOS 屏幕上,解决此错误的方法是在显示您的 UIActionSheet:

[self.view endEditing:true]; 

这可确保在显示您的 "deprecated" 操作之前关闭屏幕键盘 sheet..

(叹息。)如果有人需要我,我会在酒吧。

在 iOS 9 和 iPad 中,我必须添加一些重要的更改。以后可能会有人需要这个。

    UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Server"
                                                                   message:@"Choose server to point to"
                                                            preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *button1 = [UIAlertAction actionWithTitle:@"Development" style:UIAlertActionStyleDefault
                                                    handler:^(UIAlertAction * action) {
                                                        //code to run once button is pressed
                                                    }];
    UIAlertAction *button2 = [UIAlertAction actionWithTitle:@"Production" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        //code to run once button is pressed
    }];
    [alert addAction:button1];
    [alert addAction:button2];
    UIPopoverPresentationController *popPresenter = [alert popoverPresentationController];
    popPresenter.sourceView = self.view;
    //To present the actionsheet the bottom of screen
    popPresenter.sourceRect = CGRectMake(self.createBtn.frame.origin.x, self.view.frame.size.height, self.createBtn.frame.size.width, self.createBtn.frame.size.height);
    alert.modalPresentationStyle = UIModalPresentationPopover;
    [self presentViewController:alert animated:YES completion:nil];