在iPad上使用一个UIViewController和两个XIB处理方向变化

9
我希望能够在一个UIViewController和两个XIB(MenuView和MenuViewLandscape)的iPad应用程序中处理方向变化。因此,在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个回答

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中的File's Owner均设置为MenuViewController,并且在两个XIB中都设置了view outlet。当使用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中的File's Owner和First Responder代理对象。

然后,您只需要确保视图在界面方向上正确旋转。对于所有不在默认纵向方向上的视图,通过设置视图的transform属性,并使用适当的值调用CGAffineTransformMakeRotation()方法进行旋转,如上例所示。

仅仅旋转可能会解决您的问题,而不需要加载整个新的MenuViewController实例并将其视图设置为现有的MenuViewController视图,因为这样做可能会导致一些奇怪的生命周期和旋转事件问题,因此尝试上述示例可能更安全。它们还可以节省创建新MenuViewController实例时只需要其视图而不是完整实例的麻烦。

希望这能帮到您!

Justin


嗨,Justin。我尝试了你的解决方案,对于竖屏来说它很好用。但是对于横屏来说,所有的东西都变得模糊了。虽然旋转正确,但文本和标签都很模糊,几乎所有东西都模糊了。有什么想法吗?谢谢。 - EarlGrey

1

也许Jon Rodriguez在这里的回答可以满足您的需求:

想要为不同的iPhone界面方向使用多个nibs

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

支持多个方向的最简单方法?当应用程序处于横向模式时,如何加载自定义NIB?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接