开发者

Why aren't my views being positioned correctly on interfaceOrientation changes?

开发者 https://www.devze.com 2023-01-30 03:20 出处:网络
I have a UIViewController one UIWebView in it. I\'d like the UIWebView to be positioned in the centre of the iPad screen in landsca开发者_如何学Pythonpe and portrait modes. So, I\'ve implemented it li

I have a UIViewController one UIWebView in it. I'd like the UIWebView to be positioned in the centre of the iPad screen in landsca开发者_如何学Pythonpe and portrait modes. So, I've implemented it like this

// UIViewController
// InfoGraphicView is the UIWebView

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Overriden to allow any orientation.
    return YES;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
                                duration:(NSTimeInterval)duration {
    if (toInterfaceOrientation == UIInterfaceOrientationPortrait ||
        toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        [self layoutPortrait];
    } else {
        [self layoutLandscape];
    }
}

- (void)layoutLandscape {
    NSLog(@"Layout Landscape");
    infoGraphicView.frame = CGRectMake(100, 100, 936, 700);
}

- (void)layoutPortrait {
    NSLog(@"Layout Portrait");
    infoGraphicView.frame = CGRectMake(100, 100, 700, 936);
}

However, it's not behaving as I expected. In the above code, I would expectt he UIWebView to be 100px (or points or whatever the unit is) away from the top and the left. But it's not. In Portrait mode it appears flush with the top left of the screen, and in Landscape mode it seems to be partially offscreen in the top left.

If I set the frame as CGRectMake(-100, 100, 700, 936) then I get it positioned in the center of the screen as I'd like it to be, but I've no idea why.

As usual, there's most likely something simple I'm overlooking but I can't figure it out. Any help greatly appreciated as always.


The coordinates you set on infoGraphicView are relative to its superview, not to the screen generally. And views don't necessarily clip their subviews. Furthermore, the shape set automatically to self.view will depend on the scaling flags set in Interface Builder. However, I think that by default it is set to fill the whole screen.

That said, I think the mistake is in your use of willRotateToInterfaceOrientation:duration:. That is called before the rotation begins, so self.view has the old size (ie, it'll still be portrait sized if rotating from portrait to landscape and vice versa). Probably better to hook willAnimateRotationToInterfaceOrientation:duration: — then the correct size has been set and you'll be within the CoreAnimation block so your view will grow/shrink as part of the rotation animation.

It's also worth checking which resizing flags you have set on infoGraphicView. They'll take effect automatically, in addition to any changes you make. So you probably want to disable them all.


This probably is an issue with the view that the web view is in. The coordinate system used is that of the view’s superview. If that view isn’t being resized on rotation, then you’ll see unexpected layout like this. You can access the superview of a view through the superview property; one way to see its frame would be to use its description. Put this line in one of your layout methods:

NSLog(@"Superview: %@", [infoGraphicView superview]);

That should print out a description of the view.

Once you get that figured out, if you want the web view to have the same layout, you can use its autoresizingMask property. If you set it like this:

infoGraphicView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

Then the view will automatically change its width and height to keep the top, left, right, and bottom margins the same.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号