Reputation: 6749
I have a UIView subclass -
@interface DatePickerPopup : UIView
UIToolbar *toolbar;
UIDatePicker *datePicker;
@end
@implementation
- (id)initWithFrame:(CGRect)frame
{
NSArray *xib =
[[NSBundle mainBundle]
loadNibNamed:@"DatePickerPopup"
owner:self
options:nil];
self = [xib objectAtIndex:0];
if (self) {
}
return self;
}
@end
and the nib looks like -
In my UIViewController containing the DatePickerPopup (datePopup):
- (void)viewDidLoad
{
datePopup = [[DatePickerPopup alloc] initWithRect:CGRectZero];
CGRect newFrame = datePopup.frame;
newFrame.y = 200.0f; //lets say this aligns it to the bottom in portrait
datePopup.frame = newFrame;
// Normally happens when accessory button pressed but for brevity...
[self.view.superview addSubview:datePopup];
}
- (void)willAnimateRotationToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
CGRect screen = [[UIScreen mainScreen] bounds];
if (toInterfaceOrientation == UIInterfaceOrientationPortrait ||
toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
self.datePopup.frame =
CGRectMake(0.0f, newHeightPortrait, screen.size.width, 260.0f);
}
else
{
self.datePopup.frame =
CGRectMake(0.0f, newHeightLandscape, screen.size.width, 260.0f);
}
}
However, this gets stretched out for some reason when the orientation changes the view gets stretched to the height of the screen bounds - the navigation bar...
after viewDidLoad
after willAutorotate...
Upvotes: 4
Views: 1299
Reputation: 17918
Since your view controller appears to be managed by a navigation controller, calling [self.view.superview addSubview:datePopup];
adds your popup as a subview of a UIViewControllerWrapperView
, which is one of the private classes UIKit uses to implement the functionality of UINavigationController
. Messing with UIKit's private view hierarchy is always risky. In this case, based on the behavior you're seeing, it seems likely that UIKit expects any subview of UIViewControllerWrapperView
to be a view controller's view, so it resizes your popup accordingly.
I think the safest way to resolve this is to have your view controller's view be a wrapper that contains your tableView and, when necessary, your popup view. Unfortunately using a wrapper view means that the view controller can't be a UITableViewController
. You'll have to change the superclass to UIViewController
, set a custom tableView
property, and manually adopt the UITableViewDataSource
and UITableViewDelegate
protocols.
Note: You might be tempted to add your popover as a subview of your window, but I'm not recommending that because UIWindow
only autorotates its topmost subview corresponding to a view controller. This means that if you add your popover to your window, it won't autorotate.
EDIT: BTW, by reassigning self = [xib objectAtIndex:0];
in initWithFrame:
, you're leaking the object that was originally alloc'd. If you're going to reassign self in this way, you should release the existing object first.
Upvotes: 2
Reputation: 7644
Add the
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
method in the viewController class and return YES. If this method returns YES, only then will the device support landscape orientation. Try out this extra code and see if it helps... You can set the frame size for landscape in this method itself instead of the current method. PS: I just saw you've used a UIView instead of controller...you might want to change to controller.
Upvotes: 0