Why won't UIPickerView resize the first time I change device orientation on its parent viewController?

StackOverflow https://stackoverflow.com/questions/9767234

Question

I have a navigation-based app and say my root controller A causes a viewController B to be pushed, which has a UITableView with a few cells with UITextFields.

The first 2 UITextFields have each, as their inputView, a UIDatePicker and a UIPickerView, respectively. Also, the UIPickerView has 4 components whose UIViews are returned through

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 60, 37)];
    label.text = [NSString stringWithFormat:@"%@%i", ((component == 3) ? @"." : @""), row];
    label.textAlignment = UITextAlignmentCenter;
    label.font = [UIFont boldSystemFontOfSize:24];
    label.backgroundColor = [UIColor clearColor];
    [label autorelease];

    return label;
}

In vertical orientation, the UIPickerView looks like this: enter image description here

What I've noticed is the following:

CASE 1 - CORRECT

  1. I'm in viewController A in vertical orientation.
  2. I rotate the device / simulator from a vertical orientation to horizontal orientation
  3. I push viewController B
  4. I cause the UIPickerView to pop up

The picker frame is correctly stretched to landscape mode and the component views are still the correct size and centered:

enter image description here

BUT

CASE 2 - INCORRECT

  1. I'm in viewController A in vertical orientation.
  2. I push viewController B
  3. I rotate the device / simulator from a vertical orientation to horizontal orientation
  4. I cause the UIPickerView to pop up

In this case, the UIPickerView's components get messed up:

enter image description here

Any thoughts?

Was it helpful?

Solution

So I figured this much: Don't know why, but essentially a call to -setNeedsLayout is missing for the input view when the device rotates.

UIDatePicker (inputView = UIDatePicker) results in a picker that automatically (re) lays itself out to the right orientation, but UIPickerView (inputView = UIPickerView) does not.

So it seems like UIPickerView might be not registering for orientation changes or something of the sort. Which I solved by registering it manually. That is, in my setup code I add:

[[NSNotificationCenter defaultCenter] addObserver:weightPicker 
                                         selector:@selector(setNeedsLayout) 
                                             name:UIDeviceOrientationDidChangeNotification   
                                              object:nil];

And now the picker behaves just fine.

Also, remember to deregister with the NSNotificationCenter before the textField gets deallocated.

OTHER TIPS

For the record, a slightly cleaner version of @SaldaVonSchwartz' own answer:

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
  [myPickerView setNeedsLayout];
}

This tells myPickerView that you want to adjust the layout of a myPickerView’s subviews. Should do the trick.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top