最简单的方法来支持多个方向? 如何在应用程序处于横向模式时加载自定义的NIB?
我有一个应用程序,我想支持多个方向。 我有两个我想使用的.xib文件,myViewController.xib和myViewControllerLandscape.xib. myViewController.xib
myViewControllerLandscape.xib. myViewController.xib
存在于项目/资源中, myViewControllerLandscape.xib
存在于根项目目录中。
我想要做的是为我的旋转使用单独的NIB (myViewControllerLandscape.xib)
。 我尝试在viewDidLoad l
检测旋转viewDidLoad l
ike this:
if((self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight)) { NSLog(@"Landscape detected!"); [self initWithNibName:@"myViewControllerLandscape" bundle:nil]; }
但是我可以在gdb中看到,当应用程序以横向设备启动时,这不会被执行。 NSLog消息不会触发。 为什么是这样? 我做错了什么?
另外,如果我明确地将initWithNibName
函数调用放在viewDidLoad
方法中,那么该nib不会被加载,并且继续使用myViewController.xib文件。 我的电话有什么问题? 我应该指定一个包吗?
谢谢!
您必须加载一个视图,然后检查方向并根据需要加载另一个视图。 您在shouldAutorotateToInterfaceOrientation:
检查方向shouldAutorotateToInterfaceOrientation:
如果要旋转,则返回yes。
我使用导航控制器来pipe理转换。 如果我有纵向查看和设备旋转,我推动横向视图,然后在返回到肖像时popup横向视图。
编辑:
我在shouldAutorotateToInterfaceOrientation中为所有方向返回YES:但在应用程序启动时会调用此方法吗? 你在这个函数里面推你的视图吗?
方向常量不是您查询的全局variables,而是系统发送控制器的部分消息。 因此,在视图控制器加载之前,您无法轻松检测方向。 相反,你硬连线的应用程序开始在一个特定的方向(通常是肖像),然后立即旋转。 (请参阅移动Safari,它始终以纵向开始,然后旋转到横向。)
这是我用来replace我的肖像和风景的两种方法。
所有三个视图控制器都有这个方法:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); }
肖像有这样的:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) { [self.nav pushViewController:rightLVC animated:NO]; } if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) { [self.nav pushViewController:leftLVC animated:NO]; } }
每个景观控制器都有这个:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if (toInterfaceOrientation==UIInterfaceOrientationPortrait) { [self.nav popViewControllerAnimated:NO]; }
该应用程序开始在肖像。 如果设备的方向是横向的,则推动适当的景观。 当设备旋转到肖像时,它会popup风景。 对用户来说,它看起来像重新组织自己不同的方向相同的观点。
我发现了一个独立于导航控制器的更好的方法。 现在,当embedded导航控制器时,我有这个工作,当没有embedded(虽然我现在不使用导航控制器,所以可能有一些我没有看到的错误 – 例如PUSH过渡animation可能会有趣的,或者什么的)
两个NIB,使用苹果的命名约定。 我怀疑,在iOS 6或7,苹果可能会将此添加为“function”。 我在我的应用程序中使用它,它完美的作品:
- 触发器将旋转,不应该旋转(等待,直到旋转animation即将开始)
- 对于横向/纵向文件使用Apple命名约定(如果您希望Apple自动加载横向版本,则Default.png为Default-landscape.png)
- 重新加载新的NIB
- 这将重置
self.view
– 这将自动更新显示 - 然后它调用
viewDidLoad
(如果你手动重载一个NIB,Apple不会为你调用这个)
-(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]; } }
真的很喜欢亚当的答案 – 我稍微修改它允许在纵向或横向的初始加载笔尖
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if( !nibNameOrNil ) nibNameOrNil = [self nibNameRotated:[[UIApplication sharedApplication] statusBarOrientation]]; self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; return self; } - (NSString*) nibNameRotated:(UIInterfaceOrientation)orientation { if( UIInterfaceOrientationIsLandscape(orientation)) return [NSString stringWithFormat:@"%@-landscape", NSStringFromClass([self class])]; return [NSString stringWithFormat:@"%@", NSStringFromClass([self class])]; } -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { NSString *nibname = [self nibNameRotated:toInterfaceOrientation]; [[NSBundle mainBundle] loadNibNamed:nibname owner:self options:nil]; [self viewDidLoad]; }
我喜欢TechZen接受的答案,但正如Adam的评论中指出的那样,当你旋转到横向时,它将纵向视图控制器留在导航堆栈中。 这意味着在横向导航栏中点击后退button将使用户进入纵向视图。 同事,我正在尝试手动删除导航堆栈中的额外项目的方法。 它似乎工作,但我还没有经验,所以我没有任何承诺。 这里是示例代码:
从肖像走向景观:
[[self navigationController] pushViewController:landscapeViewController animated:NO]; [self removeFromNavigationStack:[MyPortraitViewController class]];
回到肖像:
[[self navigationController] pushViewController:portraitViewController animated:NO]; [self removeFromNavigationStack:[MyLandscapeViewController class]];
如果您不使用animation:否,您可能会收到有关导航状态的警告。
帮手:
- (void)removeFromNavigationStack:(Class)oldClass { UINavigationController *nav = [self navigationController]; NSMutableArray *newStack = [NSMutableArray array]; for (UIViewController *vc in nav.viewControllers) { if (![vc isMemberOfClass:[oldClass class]]) { [newStack addObject: vc]; } [nav setViewControllers:newStack animated:NO]; }
多一个select, TPMultiLayoutViewController 。