使用一个UIViewController和两个XIB在iPad上处理方向更改

时间:2010-11-19 06:38:57

标签: ipad rotation landscape nib

我想在iPad应用程序上使用一个UIViewController和两个XIB处理方向更改,比如说MenuView和MenuViewLandscape。

因此,在MenuViewController的willRotateToInterfaceOrientation方法中,如何在不使用其他控制器进行横向模式的情况下更改XIB?

我正在使用以下代码:

if( toInterfaceOrientation != UIInterfaceOrientationPortrait ){
    MenuViewController *landscape = [[MenuViewController alloc] 
                                        initWithNibName: @"MenuViewLandscape"
                                        bundle:nil 
                                    ];        
    [self setView:landscape.view];
}
else {
    MenuViewController *potrait = [[MenuViewController alloc] 
                                     initWithNibName: @"MenuView"
                                     bundle:nil 
                                  ];        
    [self setView:potrait.view];
}

但是当我去横向观看XIB时,横向视图控件没有正确旋转。

2 个答案:

答案 0 :(得分:12)

我不确定这个实现有什么奇怪的副作用,但尝试这样的事情,看看它是否适合你:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration {
    if (UIInterfaceOrientationIsPortrait(orientation)) {
        [[NSBundle mainBundle] loadNibNamed:@"MenuView" owner:self options:nil];
        if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
            self.view.transform = CGAffineTransformMakeRotation(M_PI);
        }
    } else if (UIInterfaceOrientationIsLandscape(orientation)){
        [[NSBundle mainBundle] loadNibNamed:@"MenuViewLandscape" owner:self options:nil];
        if (orientation == UIInterfaceOrientationLandscapeLeft) {
            self.view.transform = CGAffineTransformMakeRotation(M_PI + M_PI_2);
        } else {
            self.view.transform = CGAffineTransformMakeRotation(M_PI_2);
        }
    }
}

这假设MenuView和MenuViewLandscape XIB中的文件所有者都设置为MenuViewController,并且视图出口也设置在两个XIB中。使用loadNibNamed时,所有插座都应在旋转时正确重新连接。

如果您要为iOS 4构建,还可以使用以下代码替换loadNibNamed行:

UINib *nib = [UINib nibWithNibName:@"MenuView" bundle:nil];
UIView *portraitView = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
self.view = portraitView;

UINib *nib = [UINib nibWithNibName:@"MenuViewLandscape" bundle:nil];
UIView *landscapeView = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
self.view = landscapeView;

这些假设您要立即显示的UIView遵循XIB中的文件所有者和第一响应者代理对象。

然后,您只需要确保视图旋转正确以适应界面方向。对于未处于默认纵向方向的所有视图,请通过设置视图的transform属性并使用CGAffineTransformMakeRotation()和适当的值来旋转它们,如上例所示。

单独轮换可以解决您的问题而无需额外加载NIB。但是,加载MenuViewController的全新实例并将其视图设置为现有MenuViewController的视图可能会导致生命周期和旋转事件出现一些奇怪的行为,因此您可能更安全地尝试上述示例。当您只需要视图时,它们还可以省去创建新MenuViewController实例的麻烦。

希望这有帮助!

贾斯汀

答案 1 :(得分:1)

也许Jon Rodriguez在这里的答案会做你想要的:

Want to use muliple nibs for different iphone interface orientations

如果你有两个UIViewController类,一个用于纵向模式的基类和一个用于横向模式的子类,你几乎可以将所有代码放在基类中。这样,您可以获得单个视图控制器类的大部分优势,同时还允许您使用其他类似的解决方案:

Easiest way to support multiple orientations? How do I load a custom NIB when the application is in Landscape?