简体   繁体   English

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

[英]iPhone - UIViewController not rotating when device orientation changes

I have got my own custom UIViewController, which contains a UIScrollView with an UIImageView as it's subview. 我有自己的自定义UIViewController,它包含一个带有UIImageView的UIScrollView作为它的子视图。 I would like to make the image to auto rotate when device orientation changes, but it doesn't seem to be working... 我希望在设备方向改变时使图像自动旋转,但它似乎不起作用......

In the header file, I've got; 在头文件中,我有;

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

These components are initialised in the loadView function as below; 这些组件在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];

And I have added the following method, assuming that's all I need to make the view auto-rotate... 我添加了以下方法,假设我需要使视图自动旋转...

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

MyViewController loads fine with the image I've specified to grab from the URL, and the shouldAutorotate... function is being called, with the correct UIInterfaceOrientation, when I flip the device too. MyViewController可以很好地加载我指定要从URL中获取的图像,并且当我翻转设备时,正在使用正确的UIInterfaceOrientation调用shouldAutorotate ...函数。

However, didRotateFromInterfaceOrientation method do not get called, and the image doesn't seem to rotate itself... Could someone please point out what I need to add, or what I have done wrong here? 但是,didRotateFromInterfaceOrientation方法没有被调用,并且图像似乎没有自行旋转......有人可以指出我需要添加什么,或者我在这里做错了什么?

Thanks in advance! 提前致谢!

This may not be the right answer for you, because you don't specify the context that the UIViewController's in, but I just found an important gotcha in the Apple documentation that explains the similar problem I'm having. 这可能不适合你,因为你没有指定UIViewController所在的上下文,但我刚刚在Apple文档中发现了一个重要的问题,解释了我遇到的类似问题。

Tab bar controllers support a portrait orientation by default and do not rotate to a landscape orientation unless all of the root view controllers support such an orientation. 标签栏控制器默认支持纵向方向,除非所有根视图控制器都支持这种方向,否则不要旋转到横向方向。 When a device orientation change occurs, the tab bar controller queries its array of view controllers. 当发生设备方向更改时,选项卡栏控制器将查询其视图控制器数组。 If any one of them does not support the orientation, the tab bar controller does not change its orientation. 如果其中任何一个不支持方向,则标签栏控制器不会更改其方向。

I've noticed that there are issues when rotating a UIView that's not the first or only view as a direct child of the main window. 我注意到旋转UIView时出现问题,这不是第一个或唯一的视图作为主窗口的直接子视图。

So if your UIView is part of a Navigation Controller or a Tab View Controller, you'll also need to override shouldAutoRotateToInterfaceOrientation on the Navigation Controller or Tab View Controller. 因此,如果您的UIView是导航控制器或选项卡视图控制器的一部分,您还需要覆盖导航控制器或选项卡视图控制器上的shouldAutoRotateToInterfaceOrientation。

Also: using [UIApplication setStatusBarOrientation] helps to work around things if/when you need to do it manually. 另外:使用[UIApplication setStatusBarOrientation]有助于在需要手动执行时解决问题。

To make this kind of thing work in my application, I had to override 为了使这种事情在我的应用程序中起作用,我不得不重写

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    [self layoutSubviews];
}

and also layoutSubviews 还有layoutSubviews

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

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

I'm not sure that this is absolutely required, but it worked for me. 我不确定这是绝对必要的,但它对我有用。

Sometimes, if you add a subview to a view, it's your responsibility to make sure that the methods are passed to the subview; 有时,如果您向视图添加子视图,则您有责任确保将方法传递给子视图; a couple of days ago I wrote a short post about this. 几天前我写了一篇关于此事的短文 For example, if you have a UIViewController and add a UINavigationController as subview, you must add this code to the UIViewController if you want viewWillAppear:animated: to be called when UINavigationController.view appears: 例如,如果您有一个UIViewController并将UINavigationController添加为子视图,则必须将此代码添加到UIViewController如果您希望在UINavigationController.view出现时调用viewWillAppear:animated:

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

It might be the case that the willRotateToInterfaceOrientation and didRotateFromInterfaceOrientation method also need to be called by the superview; 可能是willRotateToInterfaceOrientationdidRotateFromInterfaceOrientation方法也需要由didRotateFromInterfaceOrientation调用; I am not really sure about this, but give it a try. 我对此并不十分确定,但试一试。

This is discussed in Apple Technical Q&A QA1688 . 这在Apple Technical Q&A QA1688中进行了讨论。

Sometimes if you stack multiple views on top of each other for some reason , the anotherController might not receive rotation event. 有时,如果由于某种原因将多个视图堆叠在一起,则anotherController可能不会接收旋转事件。

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

A lazy way (not a good design) to fix this is only add one subview on window, but initialize multiple controller on the app delegate. 修复此问题的一种懒惰方式(不是一个好的设计)只在窗口上添加一个子视图,但在应用程序委托上初始化多个控制器。 Then when you need to switch window, remove the current view and add the view you want 然后,当您需要切换窗口时,删除当前视图并添加所需的视图

[self.view removeFromSuperview];
AppDelegate *dg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[[dg window] addSubview:[[dg viewController] view]]; 

just do this if you what to rotate from landscape to portrait! 如果您要从横向旋转到肖像,请执行此操作!

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

I copied this from this link 我从这个链接复制了这个

And it works for me.... Reason why i have added this here is to make it easy for others to find. 它对我有用....我在这里添加这个的原因是为了让其他人更容易找到。 It took me many hours to find this fix: 我花了很多时间才找到这个修复:

Make a new set of class files of the UIViewController type, go into the .h file of this class and change this line 创建一组UIViewController类型的新类文件,进入该类的.h文件并更改此行

@implementation MyTabBarController: UIViewController {}
@end

to something like this 这样的事情

@implementation MyTabBarController: UITabBarController{

}

Now go into the nib file and click on the UITabBarController object and go to it's identity tab, and make it Class MyTabBarController. 现在进入nib文件并单击UITabBarController对象并转到它的标识选项卡,并使其成为Class MyTabBarController。

now in MyTabBarController.m make sure this is in it. 现在在MyTabBarController.m中确保它在其中。

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

You can probably get rid of everything else in there if you want. 如果你愿意,你可以在那里摆脱其他一切。

I just came across this having a similar problem. 我刚遇到类似的问题。 I have a series of view controllers/complex views, that all rotate perfectly and couldn't figure out why the new one I just added on wasn't rotating. 我有一系列视图控制器/复杂视图,它们完全旋转,无法弄清楚为什么我刚添加的新视图不旋转。 After a LOT of trial and error, the reason was that I wasn't calling the init method (it's the standard init method) when allocating the view controller; 经过大量的反复试验,原因是我在分配视图控制器时没有调用init方法(它是标准的init方法); eg I was doing 比如我在做

    m_timerViewController = [TimerViewController alloc];

instead of 代替

    m_timerViewController = [[TimerViewController alloc] init];

To expand on jonoogle's post. 扩展jonoogle的帖子。 I had a similar error. 我有类似的错误。 My view has a nib and my custom init: 我的视图有一个笔尖和我的自定义init:

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

didn't include the call to init the nib. 没有包含对init的调用。

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

Adding that line made my view rotate like it is supposed to. 添加该行使我的视图像它应该的那样旋转。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM