iOS Switching between Portrait and Landscape Views

daproject

macrumors newbie
Original poster
May 29, 2013
9
0
Hi Forum,

I have a question regarding an example which I saw about swaping between views (landscape and portrait). Basically explicitly defining where various UI objects should be in each view. Now I know how to make it work correctly from the example, but I really want to understand HOW it works. Any help is greatly appreciate.

Figure 1: how I have laid out my nib


ViewController.h file
Code:
#import <UIKit/UIKit.h>

@interface BIDViewController : UIViewController

@property (strong, nonatomic) IBOutlet UIView *portrait;
@property (strong, nonatomic) IBOutlet UIView *landscape;
@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *foos;
@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *bars;

- (IBAction)buttonTapped:(UIButton *)sender;

@end
With the following method in Viewcontroller.m

Code:
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
        self.view = self.portrait;
    } else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
        self.view = self.landscape;
    }
}
here is what the output looks like; When the app starts out , its correct exactly how it looks in the nib portrait view, but when you rotate it it looks like the second pic.


Question 1:
Since I have laid out the Landscape view in the nib file; how come it does not look like that when I rotate the device??


if i change rotate method to the following

Code:
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
        self.view = self.portrait;
        self.view.transform = CGAffineTransformIdentity;
        self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0));
        self.view.bounds = CGRectMake(0.0, 0.0, 320., 548);
    } else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
        self.view = self.landscape;
        self.view.transform = CGAffineTransformIdentity;
        self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90));
        self.view.bounds = CGRectMake(0.0, 0.0, 568, 300.0);
        CGRect landscape_frame = self.view.frame;
        CGRect landscape_bound = self.view.bounds;
}
THen it will work :):):)


Question 2:
Why do we have to set the value of self.view.transform to CGAffineTransformIdentity? Why cant we just call self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90));?


Question 3:
Why do we need to set the bounds? Again we specified this view in the nib


Question 4:
For debug purposes I created to CGRects as you can see and looked at their output. The bound value is just as I put them to be in my code, but the CGRect for Landscame_frame which is the origin and dimensions of the landscape view with respect to its super view is landscape_frame = origin=(x=20, y=0) size=(width=300, height=568. Where is the (0,0) point of a device in landscape mode? I dont get the (x=20,y=0).


Question 5:
Why is the frame size (width=300, height=568) ??? Hows the width of the fram 300???


landscape_frame = origin=(x=20, y=0) size=(width=300, height=568)
landscape_bound = origin=(x=0, y=0) size=(width=568, height=300)
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
I've written quite a few iOS apps, and I have always been able to avoid swapping view hierarchies when rotating views.

I would advise you to find another way to handle rotation if at all possible. Having a second view hierarchy for portrait and landscape seems fraught with problems and downsides, and no major upside that I can see.

A number of the "cons" of doing it that way:

  1. You have to lay out your interface twice, including all the outlet and action links
  2. You have to test everything twice.
  3. Anytime you change anything you have to change it twice. Add in iPhone and iPad, and now you've got 4 different view layouts to maintain. Ugh.
  4. Device rotation does not animate like users expect. Instead it JUMPS from one layout to the next.
 
Last edited by a moderator:

daproject

macrumors newbie
Original poster
May 29, 2013
9
0
I've written quite a few iOS apps, and I have always been able to avoid swapping view hierarchies when rotating views.

I would advise you to find another way to handle rotation if at all possible. Having a second view hierarchy for portrait and landscape seems fraught with problems and downsides, and no major upside that I can see.

A number of the "cons" of doing it that way:

  1. You have to lay out your interface twice, including all the outlet and action links
  2. You have to test everything twice.
  3. Anytime you change anything you have to change it twice. Add in iPhone and iPad, and now you've got 4 different view layouts to maintain. Ugh.
  4. Device rotation does not animate like users expect. Instead it JUMPS from one layout to the next.

thanks alot for your advice
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
I think the problem with your example is that there's no container view controller, like a navigation controller or tab bar controller. Are your views added directly to the window object or to a view that's added to the window object.

The window's frame and bounds don't change, regardless of the orientation. The navigation controller knows about this and it applies the transforms and resetting of frame etc. that is needed when the orientation changes.

"Normal" apps don't have to deal with this problem because they always have a container view controller. Typically only game authors think it's better to do these things manually.
 

daproject

macrumors newbie
Original poster
May 29, 2013
9
0
I think the problem with your example is that there's no container view controller, like a navigation controller or tab bar controller. Are your views added directly to the window object or to a view that's added to the window object.

The window's frame and bounds don't change, regardless of the orientation. The navigation controller knows about this and it applies the transforms and resetting of frame etc. that is needed when the orientation changes.

"Normal" apps don't have to deal with this problem because they always have a container view controller. Typically only game authors think it's better to do these things manually.
when selecting a "view" file from the interfacebuilder when creating a new XIB file it comes with a view object and thats visible on the IB dock.
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
I think the problem with your example is that there's no container view controller, like a navigation controller or tab bar controller. Are your views added directly to the window object or to a view that's added to the window object.

The window's frame and bounds don't change, regardless of the orientation. The navigation controller knows about this and it applies the transforms and resetting of frame etc. that is needed when the orientation changes.

"Normal" apps don't have to deal with this problem because they always have a container view controller. Typically only game authors think it's better to do these things manually.
No, you don't need a container view controller in order to handle auto-rotation. If you create a single view project and set it up to handle all orientations it works just fine.