在 iOS8 的 UIActionSheet 中添加 UIPickerView 的最佳解决方案是啥?

Posted

技术标签:

【中文标题】在 iOS8 的 UIActionSheet 中添加 UIPickerView 的最佳解决方案是啥?【英文标题】:What is best solution to add a UIPickerView inside a UIActionSheet in iOS8?在 iOS8 的 UIActionSheet 中添加 UIPickerView 的最佳解决方案是什么? 【发布时间】:2014-09-18 22:12:19 【问题描述】:

我知道新的 UIAlertController,但除了创建 UIViewController、将 UIPickerView 添加为子视图并以模态方式呈现之外,我还没有看到其他解决方案。这可能意味着添加委托以传递信息:(

任何人都可以发布一个使用 UIAlertController 和内部选择器的示例......都在同一个控制器中吗?

谢谢

【问题讨论】:

【参考方案1】:

对于 ios8 ActionSheetPicker-3.0 是日期选择器和其他选择器的最佳解决方案。

【讨论】:

没关系,我最终创建了新的控制器(带有选择器)......过渡平稳而愉快。我猜 Apple 已经受够了在 UIViews 上观看选择器。 我无法快速使用它。我在没有 Pod 的情况下手动添加它并使用桥接头。请帮忙【参考方案2】:

不要将 DatePicker 嵌入 UIActionSheet!从 iOS 7 开始,UIActionSheet 不应该包含任何自定义子视图,我可以向您保证,在 iOS 8 中,添加到 ActionSheet 的任何子视图都不会显示!

您可以执行以下操作并模拟 ActionSheet(下面是日期选择器的示例,该示例从底部开始动画,并且还包含一个带有按钮的 UIToolbar):

创建两个属性:

@property (strong, nonatomic) UIDatePicker *theDatePicker;
@property (strong, nonatomic) UIView *pickerView;

创建您的选择器,将其嵌入 UIView 并显示:

    -(void) createDatePickerAndShow 

        UIToolbar *controlToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, pickerView.bounds.size.width, 44)];

        [controlToolbar sizeToFit];

        UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

        UIBarButtonItem *setButton = [[UIBarButtonItem alloc] initWithTitle:@"Set" style:UIBarButtonItemStyleDone target:self action:@selector(dismissDateSet)];

        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancelDateSet)];

        [controlToolbar setItems:[NSArray arrayWithObjects:spacer, cancelButton, setButton, nil] animated:NO];


        [theDatePicker setFrame:CGRectMake(0, controlToolbar.frame.size.height - 15, theDatePicker.frame.size.width, theDatePicker.frame.size.height)];

        if (!pickerView) 
            pickerView = [[UIView alloc] initWithFrame:theDatePicker.frame];
         else 
            [pickerView setHidden:NO];
        


        CGFloat pickerViewYpositionHidden = self.view.frame.size.height + pickerView.frame.size.height;

        CGFloat pickerViewYposition = self.view.frame.size.height - pickerView.frame.size.height;

        [pickerView setFrame:CGRectMake(pickerView.frame.origin.x,
                                        pickerViewYpositionHidden,
                                        pickerView.frame.size.width,
                                        pickerView.frame.size.height)];
        [pickerView setBackgroundColor:[UIColor whiteColor]];
        [pickerView addSubview:controlToolbar];
        [pickerView addSubview:theDatePicker];
        [theDatePicker setHidden:NO];


        [self.view addSubview:pickerView];

        [UIView animateWithDuration:0.5f
                         animations:^
                             [pickerView setFrame:CGRectMake(pickerView.frame.origin.x,
                                                             pickerViewYposition,
                                                             pickerView.frame.size.width,
                                                             pickerView.frame.size.height)];
                         
                         completion:nil];

    

然后关闭 DatePicker:

    -(void) cancelDateSet     
    CGFloat pickerViewYpositionHidden = self.view.frame.size.height + pickerView.frame.size.height;    

        [UIView animateWithDuration:0.5f
                         animations:^
                             [pickerView setFrame:CGRectMake(pickerView.frame.origin.x,
                                                             pickerViewYpositionHidden,
                                                             pickerView.frame.size.width,
                                                             pickerView.frame.size.height)];
                         
                         completion:nil];
    

【讨论】:

pickerview 声明为什么? @MarkWorsnop 我不明白这个问题。请改写。【参考方案3】:

使用 UIAlertController,它是 UIActionSheet 的首选替代品。然后使用 addSubView 将 UIDatePicker 添加到 UIAlertController.view 而不是 UIActionSheet。将 UIAlertController 的标题设置为与您为 UIActionSheet 所做的相同。这是一个代码示例:

    @interface MyControllerClass() 
    @private UIDatePicker* datePicker;
    
    @end

    @implementation MyControllerClass
    ...
    -(void) showDatePicker 
    if (!datePicker)
         datePicker = [[UIDatePicker alloc] init];



  NSString *title = UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) ? @"\n\n\n\n\n\n\n\n\n" : @"\n\n\n\n\n\n\n\n\n\n\n\n" ;
        if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1)

            //Pre iOS 8
            UIActionSheet *actionSheet = [[UIActionSheet alloc]
                                          initWithTitle:title
                                          delegate:self
                                          cancelButtonTitle:nil
                                          destructiveButtonTitle:nil
                                          otherButtonTitles:@"OK", nil];

            [actionSheet addSubview:datePicker];
            [actionSheet setTag:ACTION_SHEET_DATEPICKER];
            [actionSheet showInView:self.aView];

         else 

            //for iOS 8

            UIAlertController* datePickerContainer = [UIAlertController alertControllerWithTitle: title
                                                                                         message:nil
                                                                                  preferredStyle: UIAlertControllerStyleActionSheet];

            [datePickerContainer.view addSubview:datePicker];

            //Add autolayout constraints to position the datepicker
            [datePicker setTranslatesAutoresizingMaskIntoConstraints:NO];

            // Create a dictionary to represent the view being positioned
            NSDictionary *labelViewDictionary = NSDictionaryOfVariableBindings(datePicker);

            NSArray* hConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[datePicker]-|" options:0 metrics:nil views:labelViewDictionary];
            [datePickerContainer.view addConstraints:hConstraints];
            NSArray* vConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[datePicker]" options:0 metrics:nil views:labelViewDictionary];
            [datePickerContainer.view addConstraints:vConstraints];

            [datePickerContainer addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
                [self dateSelected:nil];
            ]];

            [self presentViewController:datePickerContainer animated:YES completion:nil];

        
      
    

    ...
    @end

请在您认为合适的情况下进行修改和改进。

【讨论】:

我也在尝试在 IOS8 上进行这项工作。你能告诉我 datePicker 的声明是什么吗?【参考方案4】:

我认为第一条评论有一点错误,你必须注意它, 这是修改后的代码:

    @property (strong, nonatomic) UIDatePicker *theDatePicker;
    @property (strong, nonatomic) UIView *pickerView;
- (IBAction)createDatePickerAndShow:(id)sender;

然后链接到 createDatePickerAndShow 按钮。 之后创建您的选择器,将其嵌入 UIView 并显示:

//.................Edit to (IBAction)createDatePickerAndShow:(id)sender 

 - (IBAction)createDatePickerAndShow:(id)sender 



        UIToolbar *controlToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, _pickerView.bounds.size.width, 44)];

        [controlToolbar sizeToFit];

        UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

//............add this to disable the warning of @selector(dismissDateSet)]

      #pragma GCC diagnostic ignored "-Wundeclared-selector"

        UIBarButtonItem *setButton = [[UIBarButtonItem alloc] initWithTitle:@"done" style:UIBarButtonItemStyleDone target:self action:@selector(dismissDateSet)];

//...........Edit to UIBarButtonItemStylePlain that is supported in ios 8

        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"cancel" style:UIBarButtonItemStylePlain target:self action:@selector(cancelDateSet)];

        [controlToolbar setItems:[NSArray arrayWithObjects: cancelButton, spacer, setButton, nil] animated:NO];


        [_theDatePicker setFrame:CGRectMake(0, controlToolbar.frame.size.height - 15, _theDatePicker.frame.size.width, _theDatePicker.frame.size.height)];

        if (!_pickerView) 
            _pickerView = [[UIView alloc] initWithFrame:_theDatePicker.frame];
         else 

//.................here edit _pickerView    

    [_pickerView setHidden:NO];
        


        CGFloat pickerViewYpositionHidden = self.view.frame.size.height + _pickerView.frame.size.height;

        CGFloat pickerViewYposition = self.view.frame.size.height - _pickerView.frame.size.height;

        [_pickerView setFrame:CGRectMake(_pickerView.frame.origin.x,
                                        pickerViewYpositionHidden,
                                        _pickerView.frame.size.width,
                                        _pickerView.frame.size.height)];
        [_pickerView setBackgroundColor:[UIColor whiteColor]];
        [_pickerView addSubview:controlToolbar];
        [_pickerView addSubview:_theDatePicker];
        [_theDatePicker setHidden:NO];


        [self.view addSubview:_pickerView];

        [UIView animateWithDuration:0.5f
                         animations:^
                             [_pickerView setFrame:CGRectMake(_pickerView.frame.origin.x,
                                                             pickerViewYposition,
                                                             _pickerView.frame.size.width,
                                                             _pickerView.frame.size.height)];
                         
                         completion:nil];



    

同样解除 DatePicker:

-(void) cancelDateSet  

    CGFloat pickerViewYpositionHidden = self.view.frame.size.height + _pickerView.frame.size.height;

    [UIView animateWithDuration:0.5f
                     animations:^
                         [_pickerView setFrame:CGRectMake(_pickerView.frame.origin.x,
                                                         pickerViewYpositionHidden,
                                                         _pickerView.frame.size.width,
                                                         _pickerView.frame.size.height)];
                     
                     completion:nil];

【讨论】:

以上是关于在 iOS8 的 UIActionSheet 中添加 UIPickerView 的最佳解决方案是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS8 的 UIActionSheet 中添加 UIPickerView 的最佳解决方案是啥?

UIActionSheet _button valueforKey Crash in iOS8

iOS 8 之后,还能继续使用 UIActionSheet 和 UIAlertView 吗?

UIAlertView,UIActionSheet和iOS8推出UIAlertControl的基本使用

如何处理: UIActionSheet deprecated (iOS8) X UIAlertController not supported (iOS7)

iOS 8 在 UIActionSheet 中破坏了 UIPickerView