views:

13593

answers:

6

I have got my own custom UIViewController, which contains a UIScrollView with an UIImageView as it's subview. 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;

 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.

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?

Thanks in advance!

+1  A: 

To make this kind of thing work in my application, I had to override

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

and also 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.

frankodwyer
Thanks for the super fast response frankodwyer :)I will try overriding the didRotate delegate method you've mentioned.
Ryu
A: 

Hi frankodwyer,

OK, I have encountered a major issue. Neither of these delegate methods are being called;

    willRotateToInterfaceOrientation
    didRotateFromInterfaceOrientation

Is there something I need to setup in order for these methods to be called and rotate properly?

Ryu
I just added the methods to my ViewController.m, nothing else. I checked, and both methods get called. (p.s. it is better to put followups in comments than post them as an answer to the main question - though it is a pain to put code in comments. Or you can add further info by editing your q.)
frankodwyer
Thanks for the advise :) I've only signed up for it so bare with me for now... I will try implementing a simpler ViewController object with just an ImageView and see how it goes. Again, thanks for all the help!
Ryu
one thing that occurs to me, is you should make sure your view is wired up in Interface builder correctly (i.e. that it really is the view on the screen, or a subview of it)
frankodwyer
+2  A: 

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.

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.

Also: using [UIApplication setStatusBarOrientation] helps to work around things if/when you need to do it manually.

Ed Marty
Yes, my custom View Controller that has the ImageView I want to rotate is indeed sitting on top of a Tab View Controller. I will give that a try! Thanks Ed :)
Ryu
Ryu
A: 

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:

-(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; I am not really sure about this, but give it a try.

nutsmuggler
This does sound similar to my UIImageView issue... The super view of my custom View Controller is the Tab View Controller, so it sorta makes complement to what Ed pointed out earlier as well. Thanks nutsmuggler :)
Ryu
+4  A: 

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.

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.

lawrence
A: 

@lawrence has very good answer. I added to UITabBarController a controller that does not support landscape mode and out of the blue rotation stopped working. After adding autorotation support, everything went back to normal.

Wiktor Gworek