I have made a subclass of TTPhotoViewController, wich when I Rotate iPhone also the current image is rotated but NOT The navigation bar and the toolbar (the bar with prev and next button).
In my subclass I have overide the shouldAutorotateToInterfaceOrientation: method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
I've tried to overide willRotateToInterfaceOrientation:duration: e set up a breakpoint inside but seem that this method is never called.
Make sure all your view controllers i.e. Parent view controllers are allowing rotations.. most likely it is happening because one or more view controller is not returning TRUE for shouldAutorotateToInterfaceOrientation
I solved as follow:
TTPhotoViewController was within a TabBarController and by default TabBarController doesn't return YES for shouldAutorotateToInterfaceOrientation. So just subclass TabBarController and do something like that:
#implementation CustomTabBarController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
#end
I add a small detail: in my firts attempt to rotate the interface i've found that the deviceOrientationDidChange: in TTScrollView.m was commeted out, this is done because if you decomment this code the scroll view have a strange behaviour on landascape rotation.
Related
What I'm trying to do is the simplest concept. But, I'm just not getting any desired results.
My app is a standard Tab Bar app, all of the view controllers in each of the tabs support Portrait orientation only, which is exactly what I want.
However, in one section of the app, I display a modal view controller, which obviously covers the tab bar controller. It is a text input screen, and I would very much like this view to be able to support Landscape orientation as well as portrait. Then, once the user cancels out of that modal view controller, the tab bar controller would be displayed again, everything in portrait.
I have tried so many things, and nothing works. If I tell the app to support both orientations, then the rotations occur correctly on the modal, but also on the rest of the app, which I do not want.
I have tried implementing all the new shouldAutorotate and supportInterfaceOrientations methods, and nothing ever seems to work.
The closest attempt I had to almost working, was I created a UITabBarController category in my app delegate, to fowarded the shouldAutorotate and supportedInterfaceOrientations. This seemed to work initially, but for some reason, whenever cancelling out of my modal vc, my tab bar portion of the app was always shifted up by 20 pixels up behind the status bar?? I have no idea what that's all about.
I created a test app, in which there is no UITabBarController, and I was able to code my desired behavior with no problem, and it works perfectly. So, clearly something with regard to Tab Bar Controller is making this a difficult issue.
Please let me know what the trick is in solving this simple concept.
Thanks!
I was able to solve this by creating a couple of categories for UITabBarController and UINavigationController. Here is the code I used:
#implementation UITabBarController (rotations)
- (BOOL)shouldAutorotate
{
return [self.selectedViewController shouldAutorotate];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
#end
#implementation UINavigationController (navrotations)
- (BOOL)shouldAutorotate {
return [self.topViewController shouldAutorotate];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return [self.topViewController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
#end
Then, of course each view controller I display would simple need to respond to the shouldAutorotate and supportedInterfaceOrientations methods.
Apparently in ios6 and above, the way rotation works is different. So what you have to do is the following
In your .plist support all 4 orientations.
Subclass the UITabBarController (for e.g: CustomTabBarController)
In the CustomTabBarController put the following lines of code
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
In your app delegate or where ever you are initializing UITabBarController, replace those instances with CustomTabBarController instances.
In your modal controller put the lines
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
-(BOOL)shouldAutorotate{
return NO;
}
And it should all work.
Apparently the trick, I found is that, UITabBarController will not listen to your instructions. It will support all the orientations you mention in the .plist.
There fore you have to subclass it.
I tried doing all of the above and it works fine. Do let me know and I can send you the code if you want.
For my app rootViewController is navgationController.
I found that
pushed controller's
-(BOOL)shouldAutorotate is not getting called.
and
-(NSUInteger)supportedInterfaceOrientations get called only once.
I have checked correctly in xcode's project summary (or plist) for windows all orientation support.
I want these method to get called, as there is some uicontrol positioning code which i want to execute programmatically for orientation change.
I solved this problem by overriding (category) navigation controller's following methods
-(BOOL)shouldAutorotate;
-(NSUInteger)supportedInterfaceOrientations;
I checked which controller is getting pushed and accordingly called respective pushed controller's uicontrol positioning code in Navigation controller's following method
(NSUInteger)supportedInterfaceOrientations;
This is working fine but i dont think this is correct way. Please help me out for better solution.
You can check the following link, you need to create custom navigation to support should auto rotate
http://mobileappdevpage.blogspot.in/2012/11/how-to-use-should-autorotateios-6-with.html
The other way you can do this by creating category of UINaviagationController
code for .h file is
#interface UINavigationController (autorotation)
-(BOOL)shouldAutorotate;
-(NSUInteger)supportedInterfaceOrientations;
and code for .m file is
#implementation UINavigationController (autorotation)
-(BOOL)shouldAutorotate
{
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
[self.topViewController shouldAutorotate];
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
#end
I also faced the same issue with the navigation controller. It works fine in the case of all the pushed view controllers, but my scenario was quite different I had one viewcontroller pushed in to the navigation controller (ViewControllerParent) as the root,
NavController
-- rootViewController (ViewControllerParent)
--- ViewControllerChild1
--- ViewControllerChild2
Due to some project requirement, I was keeping the ViewControllerParent as base, and then I was adding Child viewcontroller's view as subviews to the parent based on user actions. Now I had a scenario where I wanted Child1 not to rotate and Child2 to have rotation.
The problem I faced was that my [self.topViewController] in the Navigation controller class always returns me the Parent Object since I am not pushing the Childs into the nav stack. So my shouldAutorotate methods in my Childs will never be called. So I had to put a class check in the shouldAutorotate method of my parent and then return the rotation value.
I did something like this in parent class (ViewControllerParent),it is a kind of workaround but it fixed the issue
-(BOOL)shouldAutorotate
{
BOOL allowRotation = YES;
if ([currentlyLoadedChild isKindOfClass:[Child1 class]])
{
allowRotation = NO;
}
if ([currentlyLoadedChild isKindOfClass:[Child2 class]])
{
allowRotation = YES;
}
return allowRotation;
}
-anoop
You can check for the interface orientation via
[UIApplication sharedApplication].statusBarOrientation
when the view controller is loaded, say, in viewWillAppear. There you can do your layout of subviews. Once the view is up, shouldAutorotate will be called whenever the device is turned.
Overriding UINavigationController is the right approach, but I'm not sure if you're checking the push controllers supportedInterfaceOrientations the correct way.
Look at my answer here: https://stackoverflow.com/a/12669343/253008
I had the same issue. check this answer
its a great approauch rather than applying ShouldAutoRotate
I'm having issue with auto rotating in my view which is inside a UINavitionViewController and the navigationViewcontroller is inside a tabBarViewController.
I subclassed tabBarViewController. The problem is the interfaceorientation works fine on the first view inside the tabViewController, but whenever I push to another view it doesn't work.
This is a code in subclass tabBarController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
if([self.selectedViewController isKindOfClass:[UINavigationController class]]){
return [[(UINavigationController*)self.selectedViewController visibleViewController] shouldAutorotateToInterfaceOrientation:interfaceOrientation];
} else {
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
}
You should have a UIViewController inside a UINavigationController inside a UITabBarController. The rotation is decided by shouldAutorotateToInterfaceOrientation: in your UIViewController. You need to override that method for every UIViewController to return the desired value, i.e., YES if you want it to rotate and NO if you don't want it to.
You shouldn't override shouldAutorotateToInterfaceOrientation: in UINavigationController or UITabBarController.
You have to override shouldAutorotateToInterfaceOrientation: in the view controllers for all the views in the tab bar.
If a view controller's shouldAutorotateToInterfaceOrientation: returns NO, then the tab bar will not rotate, even if the view is hidden at the time of the rotation.
I'm new to StackOverflow, and also new to objective-c.
I have tried looking for a couple weeks now to find something that gives me a hint of what to do, but I can't seem to get through this one without asking a question. It feels like it should be simple, but...
I'm having a problem with the rotation of a "rootView" controller. It should show up in landscape (which it did, before I decided to use a navigation controller). The simulator shows up in the correct orientation, but it has loaded the view rotated 90 degress left, so that the text reads from bottom to top, sideways, so you have to cock your head left. The leftmost portion of the view is visible, but the remainder of the view runs off the top of the screen. It's a large program (I'm finding that, in general, with objective-c, but enjoying it nonetheless...), but here's the gist of what I think are the important code areas:
In the appDelegate, I create a window, my rootViewcontroller, and the navcontroller:
// .h file:
UIWindow *window;
wordHelper3ViewController *viewController;
UINavigationController *navigationController;
Then in the implementation:
//.m file
- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Hide status bar
application.statusBarHidden = YES;
// --- Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
Then I release all of these in the dealloc.
In my root view, I'm doing this:
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight){
return YES;
} else {
return NO;
}
}
I implemented the following, to see what was happening, and I'm getting the log message on startup immediately:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
if (fromInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || fromInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"didRotate...");
}
}
Other than this, I don't think I'm doing anything in my code that should affect the view(s). So now, on to InterfaceBuilder:
In the attributes inspector for both the rootView and the navigation controller, the orientation is set to landscape. For the rootView, under referencing outlets, the “view” is set to file's owner. I also have an action attached to the view (touchUpInside) – I changed its class to UIButton, because I wanted to resignFirstResponder when the user clicks anywhere in the background.
For the navigationController, under Referencing outlets, it shows a connection from the navigationController to my appDelegate.
In the main window xib, the nav contoller shows up in the list, and the view controller shows up as a subview of it.
The viewcontroller also shows up on its own, in the main window's list of objects.
The only thing that stands out to me, is that when I double click the window object, IT comes up visually in portrait mode.
Does anyone have any ideas?
If you want the startup orientation to be different from the initial Portrait mode, you need to edit your info.plist file. Add an entry for "intial interface orientation" and set the value that you want.
Here's a screenshot:
If you want to rotate a UINavigationController, it will take a bit more work. See this similar question for more information.
I think your problem is that you are adding your navigation controller as a subview to the window and orientation notifications are only sent to the first subview in "window".
Try this instead.
//.m file
- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Hide status bar
application.statusBarHidden = YES;
// --- Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[viewController.view addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
Its annoying, but I've resolved orientation problems by only every having one subview in "window" and then controlling everything through that one subview (in this case viewController)
Forgive me if I'm misunderstanding, but shouldn't this
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight){
return YES;
} else {
return NO;
}
}
really be this
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
?
My view hierarchy looks like this:
tab bar -> navigation bar -> table view -> view 1 -> view 2 (UIWebView)
How can I rotate view 2 so it can be displayed in both landscape & portrait mode?
Heres your fix...just solved the same problem. The issue is the tab bar controller is responding no to the shouldRotate method.
Ignore the advice in the apple docs and create a subclass for tab view controller. In that subclass handle the shouldRotate
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Always returning YES means the view will rotate to accomodate any
orientation.
return YES; }
Heres my complete subclass
TSTabBarController.h
#import <Foundation/Foundation.h>
#interface TSTabBarController : UITabBarController {
}
#end
and the implementation file.
#import "TSTabBarController.h"
#implementation TSTabBarController
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Always returning YES means the view will rotate to accomodate any orientation.
return YES;
}
#end
If you change the class in IB for the tab bar controller you should just work.
Hope this helps.
Rich