在iOS 8及以上版本中,将UIPickerView添加到UIActionSheet无法正常工作

51

我正在把UIPickerView添加到UIActionsheet中,但在ios 7中它运行得非常完美,但在ios 8中却不起作用。请帮帮我解决这个问题。

这是我为此使用的代码:

// Objective-C
[actionSheet addSubview:pickerView];

以下是相关的截图:enter image description here

谢谢!

UIActionSheet *actionSheet;
NSString *pickerType;

- (void)createActionSheet {

    if (actionSheet == nil) {
        // setup actionsheet to contain the UIPicker
        actionSheet = [[UIActionSheet alloc] initWithTitle:@"Please select" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
        actionSheet.backgroundColor = [UIColor clearColor];

        UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
        pickerToolbar.barStyle = UIBarStyleBlackOpaque;
        [pickerToolbar sizeToFit];

        UIImageView *imageObj = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 40)];
        imageObj.image = [UIImage imageNamed:@"header.png"];
        [pickerToolbar addSubview:imageObj];

        UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [cancelBtn addTarget:self action:@selector(pickerCancel:)forControlEvents:UIControlEventTouchDown];
        // [cancelBtn setImage:[UIImage imageNamed:@"btnInviteCancel.png"] forState:UIControlStateNormal];
        [cancelBtn setTitle:@"Cancel" forState:UIControlStateNormal];

        cancelBtn.frame = CGRectMake(7.0, 7.0, 65.0, 25.0);
        [pickerToolbar addSubview:cancelBtn];

        UIButton *doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [doneBtn addTarget:self action:@selector(pickerDone:)forControlEvents:UIControlEventTouchDown];
        //[doneBtn setImage:[UIImage imageNamed:@"btnInviteDone.png"] forState:UIControlStateNormal];
        [doneBtn setTitle:@"Done" forState:UIControlStateNormal];
        doneBtn.frame = CGRectMake(258.0, 7.0, 55.0, 25.0);
        [pickerToolbar addSubview:doneBtn];

        [actionSheet addSubview:pickerToolbar];
        [pickerToolbar release];


        UIPickerView *chPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 200.0)];
        chPicker.dataSource = self;
        chPicker.delegate = self;
        chPicker.showsSelectionIndicator = YES;
        [chPicker selectRow:0 inComponent:0 animated:YES];
        [actionSheet addSubview:chPicker];
        [chPicker release];

        [actionSheet showInView:self.view];
        [actionSheet setBounds:CGRectMake(0,0,320, 464)];
    }
}

或许这个链接会有所帮助:https://dev59.com/9WbWa4cB1Zd3GeqPW3f9#11629411 - holex
6个回答

21

根据苹果文档

重要提示:在iOS 8中,UIActionSheet已被弃用。(请注意,UIActionSheetDelegate也已被弃用。)为了在iOS 8及更高版本中创建和管理操作表,请改用preferredStyle属性为UIAlertControllerStyleActionSheetUIAlertController

UIAlertController文档链接

例如:

     UIAlertController * searchActionSheet=[UIAlertController alertControllerWithTitle:@"" message:@"" preferredStyle:UIAlertControllerStyleActionSheet];

                [ searchActionSheet.view setBounds:CGRectMake(7, 180, self.view.frame.size.width, 470)];

                //yourView represent the view that contains UIPickerView and toolbar
                [searchActionSheet.view addSubview:self.yourView];
                [self presentViewController:searchActionSheet animated:YES completion:nil];

2
他们非得破坏旧有的吗?看起来这是使用操作和警报样式的新方向。 - Dean Davids
你试过这个吗?addSubview似乎不能与UIAlertController一起使用。 - Dean Davids
我尝试了不同的方向,引发了一个新问题。也许你有一些见解。https://dev59.com/8oPba4cB1Zd3GeqPup3S - Dean Davids
当我使用 addSubview 时,我会收到 EXC_BAD_ACCESS 错误。 - Phil_12d3
我能看一下你的代码和异常行吗?你是在iOS 8上部署吗? - Nada Gamal

20

这不起作用是因为苹果改变了UIActionSheet的内部实现。请参阅文档

子类化注意事项

不应该对UIActionSheet进行子类化,也不应该将视图添加到其层次结构中。如果您需要使用比UIActionSheet API提供更多的自定义功能来展示一个sheet,您可以创建自己的sheet,并使用presentViewController:animated:completion:以模态方式呈现它。


但是presentViewController只能以全屏幕视图控制器的形式模态显示 - 我们如何使其看起来类似于UIActionsheet? - Chris
2
你是完全正确的。看起来苹果现在确保没有人可以滥用这个组件。我已经调试了 UIActionSheet,目前它是一个假的 UIView 并扮演代理对象的角色。它没有任何 subviews,也没有 superview,即使可见时也不会调用 drawRect:layoutSubviews。因此,在 UIActionSheet 上进行任何视觉操作都将失败,并且没有简单的解决方法。同样的问题也适用于 UIAlertView - Marek R

8
我也遇到这个问题了,不过我有一个解决方案,希望可以帮到你。
你可以在这里下载示例代码: https://www.dropbox.com/s/yrzq3hg66pjwjwn/UIPickerViewForIos8.zip?dl=0
@interface ViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>{
    UIView *maskView;
    UIPickerView *_providerPickerView;
    UIToolbar *_providerToolbar;
}


- (void) createPickerView {
    maskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
    [maskView setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5]];

    [self.view addSubview:maskView];
    _providerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - 344, self.view.bounds.size.width, 44)];

    UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissActionSheet:)];
    _providerToolbar.items = @[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], done];
    _providerToolbar.barStyle = UIBarStyleBlackOpaque;
    [self.view addSubview:_providerToolbar];

    _providerPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - 300, 0, 0)];
    _providerPickerView.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5];
    _providerPickerView.showsSelectionIndicator = YES;
    _providerPickerView.dataSource = self;
    _providerPickerView.delegate = self;

    [self.view addSubview:_providerPickerView];
}

- (void)dismissActionSheet:(id)sender{
    [maskView removeFromSuperview];
    [_providerPickerView removeFromSuperview];
    [_providerToolbar removeFromSuperview];
}

0

1
弃用并不意味着删除。UIActionSheet在iOS 8中运行良好。 - Airsource Ltd
实际上,它们在iOS8+中无法正常工作。如果您有屏幕键盘可见,则键盘将出现在您的UIActionSheet 顶部,因此您将无法看到您的操作表选项!! 您只会看到屏幕变暗。 - Mike Gledhill
@MikeGledhill 在显示操作表之前,您需要向键盘发送resignFirstResponder消息。 - Mudriy Ilya
我尝试过了,但没有成功。键盘仍然停留在屏幕上。真正起作用的是添加这行代码:https://dev59.com/P4Pba4cB1Zd3GeqPwsIq#35334974 - Mike Gledhill
@MikeGledhill 谢谢,我知道了,稍后我会检查的兄弟) - Mudriy Ilya

-2
actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self 
                                              cancelButtonTitle:nil 
                                         destructiveButtonTitle:nil 
                                              otherButtonTitles:nil];

-4

当在最后两行中呈现UIActionSheet时,请尝试这个:

[actionSheet showFromRect:CGRectMake(0,480, 320,215) inView:self.view animated:YES];
[actionSheet setBounds:CGRectMake(0,0,320, 464)];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接