Search code examples
iphoneiosinterface-builderlandscape

Is there a method to actually *visually design* twin views (landscape + portrait) in Interface Builder?


My current design calls for some cool animation between portrait and landscape views of the data. The data representation is fairly complex, so between graphical and data elements, there are probably about 30 buttons and labels on screen at once. I've created a very tightly designed interface... now I am laying out the elements for the landscape view. The only way I've found to do this so far is to actually lay out the landscape view in code, for instance:

-(void) positionViews {
    UIInterfaceOrientation destOrientation = self.interfaceOrientation;
    if (destOrientation == UIInterfaceOrientationPortrait || destOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        //---if rotating into PORTRAIT mode
        timeBGbox.frame = CGRectMake(14, 88, 134, 14);
        targetTime.frame = CGRectMake(0, 99, 150, 29);
        energyBGbox.frame = CGRectMake(156, 88, 68, 14);
        targetEnergy.frame = CGRectMake(154, 99, 70, 29);
        speedBGbox.frame = CGRectMake(234, 88, 68, 14);
        targetSpeed.frame = CGRectMake(226, 99, 48, 29);
        speedLabel.frame = CGRectMake(264, 99, 40, 36);
    } else {
        //---if rotating to LANDSCAPE mode
        timeBGbox.frame = CGRectMake(156, 12, 152, 14);
        targetTime.frame = CGRectMake(160, 23, 150, 29);
        energyBGbox.frame = CGRectMake(156, 50, 68, 14);
        targetEnergy.frame = CGRectMake(154, 61, 70, 29);
        speedBGbox.frame = CGRectMake(234, 50, 74, 14);
        targetSpeed.frame = CGRectMake(228, 61, 48, 29);
        speedLabel.frame = CGRectMake(269, 61, 40, 36);
    }
}

This is a painstaking process, taking many trials to accomplish what I could do visually in seconds in IB. Currently, when I toggle between views in IB, and manually move elements in landscape mode, upon switching back to portrait, they are in the wrong place. I've used "springs and struts" as creatively as possible, but most of my elements need precise manual placement beyond the realm of AutoSizing.

My question is: Is there a toggle mode within IB that enables developing two graphical layouts of a view using the visual layout tools, or is numerical code the only way?


Solution

  • You can create an arbitrary number of views in your nib file. You can call one of them "portrait view" (say, the one that is also hooked up to the "view" outlet of File's Owner), and one of them "landscape view". Define them both as outlets in your UIViewController class:

    @property (nonatomic, retain) IBOutlet UIView *portraitView;
    @property (nonatomic, retain) IBOutlet UIView *landscapeView;
    

    lay out the fields in IB as you like. The trick then is that you need double the outlets in your header file:

    @property (nonatomic, retain) IBOutlet UIView *myLabel_portrait;
    @property (nonatomic, retain) IBOutlet UIView *myLabel_landscape;
    

    and in your code you need to keep both versions up to date. Best is to just update both of them when you update one of them.

    Then the code to autorotate is really easy, just:

    if ( switchingToPortrait)
        self.view = self.portraitView;
    else
        self.view = self.landscapeView;