开发者

Two NIBs, same objects (iPhone)

开发者 https://www.devze.com 2023-02-19 21:51 出处:网络
So I am setting up my application rotation, and I have been setting up all of the button translations manually using the following method:

So I am setting up my application rotation, and I have been setting up all of the button translations manually using the following method:

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)x  
                                     duration:(NSTimeInterval)duration{

 CGRect bounds = [[self view] bounds]; 

 if (UIInterfaceOrientationIsPortrait(x)) {
    [anObject setFrame: CGRectMake(0, 0, bounds.size.width, 194)];
 } 
 else { 
    [anObject setFrame: CGRectMake(0, 0, bounds.size.width, 110)];
 }

}

I'm setting up each object's position in both orientations. It seems like a horrible way of acco开发者_如何学JAVAmplishing my goal..

So now what I'd like to do is make a copy of my main nib, and set up all of the buttons' positions in landscape on the new nib. Then when the device rotates, call the corresponding nib. Is that possible/feasible/an alright way to do it?

How would I call the nib for rotation? Can I use the exact same objects with the same IBconnections?

Is there a better way?


I've used a couple of different approaches depending on the behavior I needed. See which works best for you.

  1. Find a set of rules which allow you to support both orientations using only autoresizingMask and autoresizesSubviews.

  2. Find a set of rules for the parent view's -layoutSubviews such that the subviews can be rearranged relative to the parent view's bounds. That's more work than autoresizing but better than two hardcoded positions for every subview. This often requires the creation of a deeper view hierarchy to nest several views with different -layoutSubviews behaviors to get appropriate positioning of and spacing around the visible subviews.

  3. Have two subviews, one for each orientation. Hide one when you rotate. This allows custom transitions between the subviews which you won't get if you load a new nib and replace the root view. If you load each subview from it's own nib you can then unload whichever one is no longer visible to reduce memory use. You then need to make sure both views display the same state, trigger the same IBActions, and have extra IBOutlet references (or carefully capture state from your current IBOutlets before rebinding them by loading a new subview from a nib) so you can set attributes of equivalent views in each rotation.

  4. Combine options 2 and 3 above to load different views with different layout behaviors for each rotation and shuffle subviews back and forth between them.


This is a much easier way - two NIBs, using Apple's naming convention. I suspect that in iOS 6 or 7, Apple might add this as a "feature". I'm using it in my apps and it works perfectly:

  1. triggers on WILL rotate (waits until the rotate anim is about to start)
  2. uses the Apple naming convention for landscape/portrait files (Default.png is Default-landscape.png if you want Apple to auto-load a landscape version)
  3. reloads the new NIB
  4. which resets the self.view - this will AUTOMATICALLY update the display
  5. and then it calls viewDidLoad (Apple will NOT call this for you, if you manually reload a NIB)

(NB stackoverflow.com requires this sentence here - there's a bug in the code formatter)

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    if( UIInterfaceOrientationIsLandscape(toInterfaceOrientation) )
    {
        [[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@-landscape", NSStringFromClass([self class])] owner:self options:nil];

        [self viewDidLoad];
    }
    else
    {
        [[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@", NSStringFromClass([self class])] owner:self options:nil];

        [self viewDidLoad];
    }
}
0

精彩评论

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