Wrong positioning after orientation change on iPad
Having some problems when changing the orientation of my iPadd app.
I wrote a function that lays out my subviews so I can call it when the view appears or is rotated. The function works perfectly when it is called by the "viewWillAppear" function. But when the "willAnimateRotationToInterfaceOrientation" function calls my layout function ("setPositionsForOrientation") I'm facing following issues:- When changing from portrait to landscape I have a 128px offset on the left side
- When changing from landscape to portrait I have a negative offset on the left side
I have the impression, that somehow the new frame-properties are not handled correctly, as my UIScrollViews should also resize, but they don't do it.
That's the code I wrote:
- (void)viewWillAppear:(BOOL)animated{
[self setPositionsForOrientation:self.interfaceOrientation];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)newInterfaceOrientation duration:(NSTimeInterval)duration {
[self setPositionsForOrientation:newInterfaceOrientation];
}
- (void)setPositionsForOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Position the UI elements for landscape mode
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
self.view.frame = CGRectMake(0, 0, 1024, 748);
self.menubarImage.frame = CGRectMake(0, 0, 1024, 121);
self.backgroundImage.frame = CGRectMake(0, 0, 1024, 748);
self.mainCategories.frame = CGRectMake(6, 6, 1012, 55);
self.subCategories.frame = CGRectMake(58, 79, 960, 30);
self.moviesContainer.frame = CGRectMake(6, 204, 1012, 456);
self.searchButton.frame = CGRectMake(935, 709, 80, 30);
}
// Position the UI elements for portrait mode
else {
self.view.frame = CGRectMake(0, 0, 768, 1004);
self.menubarImage.frame = CGRectMake(0, 256, 768, 121);
self.toolbarImage.frame = CGRectMake(0, 924, 768, 80);
self.backgroundImage.frame = CGRectMake(0, 256, 768, 748);
self.mainCategories.frame = CGRectMake(6, 262, 756, 55);
self.subCategories.frame = CGRectMake(58, 335, 704, 30);
self.moviesContainer.frame = CGRectMake(6, 460, 756, 456);
self.searchButton.frame = CGRectMake(680, 963, 80, 30);
}
}
And here are some pictures to illustrate my problem..
Layout in IB (All subviews have contentMode set to Top-Left)
http://www.abload.de/image.php?img=interfacebuilderl9ey.png
Portrait mode shown correctly / strange
http://www.abload.de/i开发者_开发技巧mage.php?img=portrait_oklxf1.png
http://www.abload.de/image.php?img=portrait_failma8y.png
Landscape mode shown correctly / strange
http://www.abload.de/image.php?img=landscape_ok4z2l.png
http://www.abload.de/image.php?img=landscape_failvzuy.png
What have I done wrong and more important, how can I fix it?
I found this post which describes the usual way, but I don't get how I can override my views "layoutSubviews" method, as the view is just a property of my UIViewController..If you want to create you own subclass of UIView and set it to UIViewController so you can implement layoutSubviews method, is very easy actually!.
UIViewController does not creates a view it expects the user to set the view but when using Interface BUilder there is a UIView already set for us.
To change the view do:
- Create your subclass, here I will assume it is called MyView, and put there all your UI stuff (toolbars, buttons, etc).
- Open your view controller file in IB (the *.xib)
- Select the view (the view that we are changing)
- Go to the Identity Inspector (or press Cmd+4)
- Enter "MyView" in the class identity field
Since you put all your UI elements in the view as ivar you cannot access them from your UIViewController anymore right? So, make sure you have the correct accessors/properties and methods to handle your view (and its ivars) from UIViewController. ;)
Good Luck ;)
EDIT:2011/01/17
When you are in your controller and do [self.view xyz] you get the warning right? That is because a UIViewController's view is declared to be an UIView object. And you subclassed UIView and set it in IB. So everytime you access the view you have to cast it or the compiler will think it is still the normal UIView which does not have the methods you have declared in MyView. Do like this:
[(MyView *)self.view xyz]; //and for that don't forget to #import "MyView.h"
This should work. But I don't understand why then got: "property 'view' type does not match super class 'UIViewController' property type" First try what I just said ;) Are you sure you Declared MyView as:
@interface MyView: UIView{
...
}
@property (...) XYZ *xyz;
...
@end
I added following code in the MyView class in the .m file and it helped me out of my misery:
- (void)awakeFromNib
{
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
精彩评论