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。
答案 0 :(得分:8)
我想我找到了一种方法 - 可能是正确的方法 - 来做到这一点。
以下是一些代码:
// 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];
}
为什么这样做?
所有方向更改都流经视图控制器,而不是视图。
据我所知,您添加到窗口的第一个视图或子视图会有一些特殊的味道。如果该视图具有视图控制器,则窗口会将其计算出来。
也就是说,对于第一个子视图,您可以考虑以下代码:
[window addSubview:masterVC.view];
做这样的事情(不是真正的方法!):
[window addSubview:masterVC.view withViewController:masterVC];
我对此不了解。我发现我可以用第一个子视图执行此操作,而不是其他子视图,这非常令人困惑。欢迎更多信息,如果这对您有所帮助,请告诉我。
答案 1 :(得分:1)
显然,如果您将视图添加为viewS的子视图,它将正确旋转。这对我的项目来说不是一个很好的解决方案,但看起来它可能是唯一的解决方法。
答案 2 :(得分:0)
不幸的是,只会询问您的子视图在方向发生变化时支持的方向。
所以,如果我知道它已被更改,我最终会在将新视图控制器推入堆栈之前设置方向:
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
是的,这是一个不受支持的电话。
答案 3 :(得分:0)
您可以使用UIApplication对象强制特定的设备方向。
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
答案 4 :(得分:-1)
是的,我相信你必须通过拥有多个XIB来解决这个问题。我记得通过我过去读过的一本书看到了这个解决方案。如果没有,你可以在视图中使用翻译和对象的位置......更好的是有单独的XIB。
答案 5 :(得分:-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);
}
}