Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIDatePicker in UIActionSheet layering problem

Someone posted this code in another question to put a UIDatePicker in a UIAlertSheet:

UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:@"Date Picker" 
                                                  delegate:self
                                         cancelButtonTitle:@"Cancel"
                                    destructiveButtonTitle:nil
                                         otherButtonTitles:nil];

// Add the picker
UIDatePicker *pickerView = [[UIDatePicker alloc] init];
pickerView.datePickerMode = UIDatePickerModeDate;
[menu addSubview:pickerView];
[menu showInView:self.view];        
[menu setBounds:CGRectMake(0,0,320, 500)];

CGRect pickerRect = pickerView.bounds;
pickerRect.origin.y = -100;
pickerView.bounds = pickerRect;

[pickerView release];
[menu release];

I have modified it to this:

    UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:nil
                                                      delegate:nil
                                             cancelButtonTitle:@"Done"
                                        destructiveButtonTitle:nil
                                             otherButtonTitles:nil];

    // Add the picker
    UIDatePicker *pickerView = [[UIDatePicker alloc] init];
    pickerView.datePickerMode = UIDatePickerModeCountDownTimer;
    [menu addSubview:pickerView];
    [menu showInView:self.navigationController.tabBarController.view];        
    [menu setBounds:CGRectMake(0,0,320, 516)];
    [pickerView setFrame:CGRectMake(0, 85, 320, 216)];

This yields an alert sheet correctly positioned (ignore the nil delegate; this is just for display purposes). The problem lies here:

alt text
(source: hosting-wizards.com)

As you can see, above the minute scroller, there is a layering problem. I have not confirmed if this occurs on the device. Any ideas as to why this is happening?

Another question: Why does the setBounds selector on the UIActionSheet have the Y-size set at such a high value for correct display? Setting the Y-size to 480 should create a full screen display, should it not? Setting this value to zero makes it nearly invisible.

SIDE NOTE: The code pasted above does not position the UIDatePicker in the same place that it is in the picture, but the layering problem occurs no matter where the UIDatePicker is placed. The layering issue is only on the top, not on the bottom.

like image 563
jmeado3 Avatar asked Jul 28 '09 01:07

jmeado3


4 Answers

You will avoid the display problem and get a much better looking result if you simply put the UIDatePicker in a new view and implement the slide-up-from-the-bottom behavior yourself. It's not that hard.

  1. Create a UIView containing a date picker and a toolbar with a Done button on it. (In code or use Interface Builder, doesn't matter.)
  2. Add the popup view as a subview of your main view.
  3. Set the popup view's frame so that it is off the bottom of the screen: frame.origin.y = CGRectGetMaxY(mainView.bounds)
  4. Call [UIView beginAnimations:nil context:nil]
  5. Set the frame to where it should be: frame.origin.y -= CGRectGetHeight(popupView.bounds)
  6. Call [UIView commitAnimations]

(Note that the frame setting stuff is pseudocode.)

That's it. Do it in reverse when you need to dismiss the view. I think it will be worth the trouble; sticking a date picker in a UIActionSheet looks incredibly tacky.

like image 158
benzado Avatar answered Nov 14 '22 17:11

benzado


Using benzado's steps above, here's roughly what your code would look like if you use a UIView instead of an ActionSheet:

int height = 255;

//create new view
UIView * newView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, 320, height)];
newView.backgroundColor = [UIColor colorWithWhite:1 alpha:1];

//add toolbar
UIToolbar * toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, 320, 40)];
toolbar.barStyle = UIBarStyleBlack;

//add button
UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:nil];
toolbar.items = [NSArray arrayWithObjects:infoButtonItem, nil];

//add date picker
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
datePicker.hidden = NO;
datePicker.date = [NSDate date];
datePicker.frame = CGRectMake(0, 40, 320, 250);
[datePicker addTarget:self action:nil/*@selector(changeDateInLabel:)*/ forControlEvents:UIControlEventValueChanged];
[newView addSubview:datePicker];

//add popup view
[newView addSubview:toolbar];
[self.view addSubview:newView];

//animate it onto the screen
CGRect temp = newView.frame;
temp.origin.y = CGRectGetMaxY(self.view.bounds);
newView.frame = temp;
[UIView beginAnimations:nil context:nil];
temp.origin.y -= height;
newView.frame = temp;
[UIView commitAnimations];

I agree, it looks a lot better than using ActionSheets which are designed to display buttons, not pickers. You still need to add your own action handlers on the "Done" button and when the user changes the picker but this should get you started.

like image 41
Jonesy Avatar answered Nov 14 '22 17:11

Jonesy


Do you really need to put your picker on the UIActionSheet? Why don't you use an inputView property from UIResponder class? It shows UIDatePicker (or any other view) automatically when your control (e.g. UITextField) becomes a first responder. An example of using inputView with source code can be found here: Working with pickers.

like image 31
lechec Avatar answered Nov 14 '22 19:11

lechec


try this

[menu sendSubviewToBack: pickerView];

and also move your picker 10 pixels down as you see in the screenshot it is not aliged to the bottom, might be

[pickerView setFrame:CGRectMake(0, 100, 320, 216)];
like image 1
yasirmturk Avatar answered Nov 14 '22 19:11

yasirmturk