2

I'm aware of the new UIAlertController, but I haven't seen a solution other than Creating a UIViewController, adding the UIPickerView as a subview and presenting it modally.. which probably means adding delegates to pass info :(

Can anyone post an example of using UIAlertController with a picker inside.. all in the same controller?

Thanks

elemento
  • 345
  • 3
  • 11

4 Answers4

1

For the iOS8 ActionSheetPicker-3.0 is the best solution for Date picker and other pickers.

animation

skywinder
  • 21,291
  • 15
  • 93
  • 123
Jaha Rabari
  • 173
  • 8
  • 1
    Nevermind, I ended up creating new controllers instead (with pickers)... transition is smooth and pleasant. I guess Apple had enough of watching pickers on top of UIViews. – elemento Sep 22 '14 at 19:58
  • I am not able to use it with swift. I am adding it manually without Pods and using a bridging header. Help please – NotABot Dec 26 '16 at 08:31
1

Don't embed a DatePicker into an UIActionSheet! Since iOS 7 the UIActionSheet isn't supposed to hold any custom subviews and I can assure you that in iOS 8 any subview added to an ActionSheet doesn't show!

What you could do instead and simulate an ActionSheet is the following (below it's an example of a Date Picker that animates from the bottom and also holds a UIToolbar with buttons above it):

Create two properties:

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

Create your picker, embed it into the UIView and show:

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

    }

And to dismiss the 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];
    }
Raceimaztion
  • 9,494
  • 4
  • 26
  • 41
Razvan
  • 4,122
  • 2
  • 26
  • 44
1

Use a UIAlertController, the preferred replacement for UIActionSheet. Then add the UIDatePicker using addSubView to the UIAlertController.view instead of the UIActionSheet. Set the title of the UIAlertController the same as you would have done for the UIActionSheet. Here's a code sample:

    @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

Please amend and improve as you see fit.

Lion
  • 872
  • 1
  • 17
  • 43
user59950
  • 31
  • 3
0

I think there is a little mistake in the first comment you have to pay attention for it, This is the code after editing:

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

and then link to the createDatePickerAndShow button. after that Create your picker, embed it into the UIView and show:

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



    }

And to dismiss the DatePicker the same:

-(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];
}
Diaa Den
  • 1,024
  • 10
  • 5