iPhone - 设备方向改变时,UIViewController不会旋转

14

我有自己的自定义UIViewController,其中包含一个UIScrollView,并将UIImageView作为其子视图。当设备方向改变时,我想让图像自动旋转,但似乎没有起作用...

在头文件中,我有;

@interface MyViewController : UIViewController <UIScrollViewDelegate> {
    IBOutlet UIScrollView   *containerView;
    UIImageView *imageView;
}

这些组件在loadView函数中被初始化,如下所示;

    containerView = [[UIScrollView alloc] initWithFrame:frame];

    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://..."]];
    UIImage *image = [[UIImage alloc] initWithData:data];
    imageView = [[UIImageView alloc] initWithImage:image];
    [image release];

    [containerView addSubview:imageView];

我已经添加了下面的方法,假设这就是我需要让视图自动旋转的全部内容...

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

我已经在MyViewController中成功从指定的 URL 获取了图片,当我翻转设备时,shouldAutorotate... 函数被调用,并且 UIInterfaceOrientation 也是正确的。

然而,didRotateFromInterfaceOrientation 方法没有被调用,图片似乎也没有自动旋转。 请问有谁能指出我需要添加什么,或者我做错了什么吗?

先感谢您!

9个回答

25

这可能不是适合您的答案,因为您没有指定UIViewController的上下文,但我在苹果文档中发现了一个重要的陷阱,它解释了我遇到的类似问题。

选项卡栏控制器默认支持竖屏方向,并且仅当所有根视图控制器都支持此方向时,才会旋转到横屏方向。当设备方向更改时,选项卡栏控制器会查询其视图控制器数组。如果其中任何一个不支持该方向,则选项卡栏控制器不会更改其方向。


3

我注意到在旋转不是第一个或唯一的视图作为主窗口的直接子视图时会出现问题。

因此,如果您的UIView是导航控制器或选项卡视图控制器的一部分,您还需要重载导航控制器或选项卡视图控制器上的shouldAutoRotateToInterfaceOrientation。

另外:如果/当您需要手动操作时,使用[UIApplication setStatusBarOrientation]有助于解决问题。


是的,我想要旋转的自定义视图控制器确实位于选项卡视图控制器之上。我会尝试一下!谢谢 Ed :) - Ryu
感谢 Ed。我已经实现了我的自定义UITabViewController和UINavigationController,现在它们都工作得很好,就像你说的一样 :)接下来,我还需要让一些视图始终保持竖屏方向,所以下一步是处理这个问题! - Ryu

1

这个问题在Apple Technical Q&A QA1688中有所讨论。

有时,如果您将多个视图叠加在一起出于某种原因,anotherController可能无法接收旋转事件。

[myWindow addSubview:primaryViewController.view];
[myWindow addSubview:anotherController.view];

一种懒惰的方式(不是一个好的设计)来解决这个问题是只在窗口上添加一个子视图,但在应用程序委托中初始化多个控制器。然后当您需要切换窗口时,删除当前视图并添加您想要的视图。
[self.view removeFromSuperview];
AppDelegate *dg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[[dg window] addSubview:[[dg viewController] view]]; 

1
为了让我的应用程序能够正常工作,我不得不覆盖重写这个东西。
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    [self layoutSubviews];
}

还有layoutSubviews

- (void)layoutSubviews
{
    NSLog(@"layoutSubviews called");

    ...recalc rects etc based on the new self.view.bounds...
}

我不确定这是否绝对需要,但它对我起作用了。


谢谢您的超快速回复,frankodwyer :) 我会尝试覆盖您提到的didRotate委托方法。 - Ryu
嗨,frankodwyer,好的,我遇到了一个重大问题。 这两个委托方法都没有被调用; willRotateToInterfaceOrientation didRotateFromInterfaceOrientation我需要设置什么才能使这些方法被调用并正确旋转? - Ryu
我只是在我的ViewController.m中添加了方法,没有其他的。我检查过,两个方法都被调用了。(附言:最好将后续问题放在评论中而不是将它们作为答案发布在主要问题中——尽管在评论中放置代码很麻烦。或者您可以通过编辑您的问题添加更多信息。) - frankodwyer
谢谢建议 :) 我只是注册了它,所以现在请耐心等待我... 我会尝试实现一个更简单的 ViewController 对象,只包含 ImageView,并看看效果如何。 再次感谢您的所有帮助! - Ryu
我想到的一件事是,你应该确保你的视图在Interface Builder中正确连接(即它真的是屏幕上的视图或其子视图)。 - frankodwyer

1
有时,如果您将子视图添加到视图中,则需要确保方法传递给子视图;几天前我写了一篇简短的文章。例如,如果您有一个UIViewController并添加了一个UINavigationController作为子视图,则必须将此代码添加到UIViewController中,如果您希望在UINavigationController.view出现时调用viewWillAppear:animated:

-(void)viewWillAppear:(BOOL)animated { 
[super viewWillAppear:animated];
[projectNavigationController viewWillAppear:animated];
}

可能需要由父视图调用 willRotateToInterfaceOrientationdidRotateFromInterfaceOrientation 方法;我不太确定,但可以尝试一下。


这听起来与我的UIImageView问题相似... 我自定义的视图控制器的超级视图是选项卡视图控制器,所以它也与Ed之前指出的内容相辅相成。谢谢nutsmuggler :) - Ryu

0

如果你想从横屏旋转到竖屏,只需执行以下操作!

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

0
我刚刚遇到了一个类似的问题。我有一系列的视图控制器/复杂视图,它们都可以完美地旋转,但是我无法弄清楚为什么我刚刚添加的新视图没有旋转。经过大量的试错,原因是在分配视图控制器时我没有调用init方法(这是标准的init方法); 例如,我之前做的是:
    m_timerViewController = [TimerViewController alloc];

而不是

    m_timerViewController = [[TimerViewController alloc] init];

0

我从这个链接复制了这段代码。

它对我有效... 我在这里添加的原因是为了让其他人更容易找到。我花了很多时间才找到这个解决方法:

创建一个新的UIViewController类型的类文件集,进入该类的.h文件并更改此行:

@implementation MyTabBarController: UIViewController {}
@end

转换为类似于这样的格式

@implementation MyTabBarController: UITabBarController{

}

现在进入nib文件,点击UITabBarController对象并转到其身份选项卡,将其设置为Class MyTabBarController。

现在在MyTabBarController.m中确保包含此内容。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io {
     return YES;
}

如果你想的话,可以把里面的其他东西都删掉。


1
抱歉,你完全没有回答他的问题!他明确表示他已经有了那行代码! - Rich

0

为了进一步解释jonoogle的帖子。我遇到了类似的错误。我的视图有一个nib和自定义init:

- (id)initWithCategory:(Category *)category inManagedObjectContext:context{

没有包含初始化nib的调用。

self = [super initWithNibName:nil bundle:nil];

加上那行代码后,我的视图就像预期的那样旋转了。


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