支持多种方向的最简单方法?当应用程序在Landscape中时如何加载自定义NIB?

Pet*_*jas 35 iphone xib uiviewcontroller nib iphone-sdk-3.0

我有一个应用程序,我想支持多个方向.我有两个.xib文件,我想使用myViewController.xib myViewControllerLandscape.xib. myViewController.xib并存在于project/Resources中,myViewControllerLandscape.xib并存在于根项目目录中.

我想要做的是使用单独的NIB (myViewControllerLandscape.xib)进行轮换.我尝试在viewDidLoad like中检测旋转:

if((self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight))
 {
  NSLog(@"Landscape detected!");
  [self initWithNibName:@"myViewControllerLandscape" bundle:nil];

 }
Run Code Online (Sandbox Code Playgroud)

但我可以在gdb中看到,当应用程序以横向设备启动时,不会执行此操作.NSLog消息不会触发.为什么是这样?我做错了什么?

此外,如果我initWithNibNameviewDidLoad方法中明确地放置了函数调用,则不会加载该nib,并继续使用myViewController.xib文件.我的电话有什么问题?我应该指定捆绑吗?

谢谢!

Ada*_*dam 58

我发现了一种独立于导航控制器的更好的方法.现在,当嵌入在导航控制器中时,我有这个工作,当没有嵌入时(虽然我现在没有使用导航控制器,所以可能有一些我没见过的错误 - 例如PUSH过渡动画可能会去好笑,或者其他什么)

两个NIB,使用Apple的命名约定.我怀疑在iOS 6或7中,Apple可能会将其添加为"功能".我在我的应用程序中使用它并且它完美地工作:

  1. WILL上的触发器旋转,不应该旋转(等待旋转动画即将开始)
  2. 对横向/纵向文件使用Apple命名约定(如果希望Apple自动加载横向版本,则Default.png为Default-landscape.png)
  3. 重新加载新的NIB
  4. 重置self.view- 这将自动更新显示
  5. 然后它调用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];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是我总是进行方向更改的方法,让额外的视图控制器变得愚蠢,不必要和浪费资源.更不用说上面的其他人指出它在堆栈中留下视图控制器/视图等. (4认同)

Tec*_*Zen 40

您必须加载一个视图,然后检查方向并在需要时加载另一个视图.shouldAutorotateToInterfaceOrientation:如果要旋转,请检查返回是的方向.

我使用导航控制器来管理过渡.如果我有纵向视图并且设备旋转,我会推动横向视图,然后在返回纵向时弹出横向视图.

编辑:

我在shouldAutorotateToInterfaceOrientation中为所有方向返回YES:但是当应用程序启动时会调用它吗?你是否在这个功能中推动你的观点?

方向常量不是您查询的全局变量,而是系统发送控制器的部分消息.因此,在视图控制器加载之前,您无法轻松检测方向.相反,您硬连线应用程序以特定方向(通常是纵向)开始,然后立即旋转.(参见移动Safari.它始终以纵向开始,然后旋转到横向.)

这是我用来换出纵向和横向视图的两种方法.

所有三个视图控制器都有这种方法:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
Run Code Online (Sandbox Code Playgroud)

肖像有这个:

- (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];
    }
}
Run Code Online (Sandbox Code Playgroud)

每个景观控制器都有:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

    if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
        [self.nav popViewControllerAnimated:NO];
    }
Run Code Online (Sandbox Code Playgroud)

该应用程序以纵向开始.如果设备的方向是横向的,它会推动适当的景观.当设备旋转回纵向时,它会弹出景观.对于用户来说,它看起来像是相同的视图,为不同的方向重新组织自己.

  • 这个答案ALMOST有效 - 不幸的是,因为它在Nav堆栈中插入了一个额外的项目,它会破坏UINavigationBar(你得到一个额外的条目).我不得不添加一堆逻辑来智能地隐藏导航栏,当推动风景或弹出到风景时,并在推动其他任何东西时取消隐藏 (2认同)

ame*_*gin 5

真的很喜欢Adam的答案 - 我稍微修改它以允许在纵向或横向中初始加载笔尖

- (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];
}
Run Code Online (Sandbox Code Playgroud)