views:

1655

answers:

3

Note: This may be a duplicate of Subview Doesnt AutoSize When Added to Root View Controller


I have an iPad app that switches between different views in its main window. The view-switching code looks like this:

- (void)switchToViewController:(UIViewController*)viewController {
    if (currentViewController != viewController) {
        [currentViewController.view removeFromSuperview];
        currentViewController = viewController;
        [window addSubview:viewController.view];
    }
}

The problem is that when the new view (a UISplitView) appears in landscape orientation, it is not sized to fill the entire window. There is a large empty black space on the right. It looks like the view is only 768 pixels wide, rather than the 1024-pixel width of the landscape window.

If I rotate the device to portrait and then back to landscape, the view sizes itself properly.

If the device is in portrait orientation, everything works fine. The UISplitView also gets sized properly if it is the first view I show. The problem only occurs if I switch to it after another view has been shown, in landscape.

So, is there some way to force iPhone OS to resize the view after it has been added to the window?

I've tried calling sizeToFit, and setNeedsLayout. I've also tried setting the view's bounds to the window's bounds, and I've tried setting the frame to match the previous view's frame.

+1  A: 

The window may include other UI elements besides your view. The 20 pixel difference in your example is the height of the status bar.

[[UIApplication sharedApplication] statusBarFrame].height;

Neither the window nor screen rotate. Getting their frames and using them for a rotated view will only work if you have switched the height and width.

If you are using a UIViewController, try returning YES from this method:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation; // Override to allow rotation. Default returns YES only for UIDeviceOrientationPortrait
drawnonward
Things aren't just 20 pixels off; they are 320 pixels off.I am returning YES from shouldAutorotateToInterfaceOrientation:, and everything shows in the proper orientation. It's just the view size that is wrong.
Kristopher Johnson
The 20 pixels I was talking about was in 1004 vs 1024 and 748 vs 768. You are leaving room for the status bar by hard coding the value 20 into your width or height.
drawnonward
+2  A: 

This works, but it seems a little hacky:

- (void)switchToViewController:(UIViewController *)viewController {
    if (viewController != currentViewController) {
        UIInterfaceOrientation orientation = currentViewController.interfaceOrientation;
        [currentViewController.view removeFromSuperview];

        currentViewController = viewController;
        UIView *view = viewController.view;

        // Set appropriate view frame (it won't be autosized by addSubview:)
        CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
        if (UIInterfaceOrientationIsLandscape(orientation)) {
            // Need to flip the X-Y coordinates for landscape
            view.frame = CGRectMake(appFrame.origin.y, appFrame.origin.x, appFrame.size.height, appFrame.size.width);
        }
        else {
            view.frame = appFrame;
        }

        [window addSubview:view];
    }
}
Kristopher Johnson
+1  A: 

Hello

I got the same problem, but i fixed it with this lines of code:

- (void)changeRow:(NSNotification *)notification {
[window addSubview:new.view];
[old.view removeFromSuperview];
[new.view removeFromSuperview];
[window addSubview:new.view];

}

You must add the new view, then remove the old and the new and then add the new view. I don't know why, but that works.

C3000