4

github上提供了一个最小的说明性 Xcode 项目。

在我的 UIWindow 上,当我添加第二个(和后续的)UITableView 作为子视图时,它们不会正确旋转,因此会出现在侧面。这仅在模拟器中进行测试。这是给你的一个小代码:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    ShellTVC* viewA = [[ShellTVC alloc] initWithTitle:@"View A"];
    ShellTVC* viewB = [[ShellTVC alloc] initWithTitle:@"View B"];

    // The first subview added will rotate to landscape correctly. 
    // Any subsequent subview added will not.

    // You may try this by various commentings and rearranging of these two statements.

    [window addSubview:[viewA tableView]];
    [window addSubview:[viewB tableView]];

    [window makeKeyAndVisible];
}

viewB 出现在侧面。注释掉 viewB 的 addSubview,viewA 正确显示。仅对 viewA 执行此操作,并且 viewB 会正确显示。

我不是通过 NIB 创建这些 UITableViewControllers,尽管 UIWindow 是。

如果你想知道,ShellTVC 是一个 UITableViewController,并实现了这个方法:

- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

另外,我已将 plist 文件中的 UIInterfaceOrientation 设置为 UIInterfaceOrientationLandscapeLeft。

可能相关的 - 和未回答的 - SO 问题在这里这里

4

6 回答 6

8

我想我找到了一种方法——可能是正确的方法——来做到这一点。

  1. 创建一个“主” UIViewController 子类,它实现了 shouldAutorotate...,并将其添加为窗口上的唯一视图。
  2. 要在 viewA 或 viewB 之间切换,请在此主视图控制器上使用 dismissModalViewControllerAnimated: & presentModalViewController:animated: 的组合。

这是一些代码:

// this doesn't really do much but implement shouldAutorotate...
@interface MasterViewController : UIViewController
@end

@implementation MasterViewController
- (BOOL) shouldAutorotateToInterfaceOrientation(UIInterfaceOrientation)interfaceOrientation {
     return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
@end

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
    MasterViewController* masterVC;
    UIViewController* activeTVC;
    UIViewController* onDeckTVC;
}
@end

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    UIViewController* masterVC = [[MasterViewController alloc] init];        
    activeTVC = [[ShellTVC alloc] initWithTitle:@"View A"];
    onDeckTVC = [[ShellTVC alloc] initWithTitle:@"View B"];
    [window addSubview:masterView.view];
    [window makeKeyAndVisible];
    [masterVC presentModalViewController:activeTVC animated:NO];
}

// you would call this to toggle between "View A" and "View B"
- (void)toggleTVC {
    UITableViewController *hold = activeTVC;
    activeTVC = onDeckTVC;
    onDeckTVC = hold;
    [masterVC dismissModalViewControllerAnimated:NO];   
    [masterVC presentModalViewController:activeTVC animated:NO];
}

为什么这行得通?

  1. 所有方向更改都通过视图控制器,而不是视图。

  2. 据我所知,您添加到窗口的第一个视图或子视图会得到一些特殊的调味料。如果该视图具有视图控制器,则窗口会计算出来。

也就是说,仅对于第一个子视图,您可以考虑以下代码:

[window addSubview:masterVC.view];

做这样的事情(不是真正的方法!):

[window addSubview:masterVC.view withViewController:masterVC];

我对此一无所知。我发现我可以使用第一个子视图而不是其他子视图来做到这一点,这非常令人困惑。欢迎提供更多信息,如果这对您有帮助,请告诉我。

于 2010-04-11T02:36:05.363 回答
1

显然,如果您将 viewB 添加为 viewA 的子级,它将正确旋转。这对我的项目来说不是一个很好的解决方案,但看起来它可能是唯一的解决方法。

于 2010-04-10T02:01:44.643 回答
0

不幸的是,当方向发生变化时,只会询问您的子视图它们支持的方向。

因此,如果我知道它已更改,我最终会在将新视图控制器推入堆栈之前设置方向:

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; 

是的,这是一个不受支持的呼叫。

于 2009-10-27T17:49:19.113 回答
0

您可以使用 UIApplication 对象来强制特定的设备方向。

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
于 2009-10-27T18:53:20.517 回答
-1

这应该有效。

- (void)viewDidLoad {
    if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) || 
        ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)) 

    {
        self.view.frame = CGRectMake(0, 0, 1024, 748);

    } else {
        self.view.frame = CGRectMake(0, 0, 768, 1004);
    }
}
于 2010-12-10T08:43:38.757 回答
-1

是的,我相信你必须通过拥有多个 XIB 来解决这个问题。我记得通过我过去读过的一本书看到了这个解决方案。如果没有,您可以在视图中使用平移和对象位置...最好有单独的 XIB。

于 2010-08-27T15:10:22.920 回答