In my mainWindow.xib, I have this setup.
1) UINavigationController containing several viewControllers.
2) UIViewController containing a scrollview holding several buttons.
I've defined them in Appdelegate.h to get the control and attached them to window
[window addSubview:navigationController.view]; // navigationController
[window addSubview:container.view]; //scrollview
[window makeKeyAndVisible];
Now I'm using the same standard code for InterfaceOrientation (In the AppDelegate and in all subsequent viewControllers in it.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation==UIInterfaceOrientationPortrait ||interfaceOrientation==UIInterfaceOrientationPortraitUpsideDown) ? YES : NO;
}
The NavigationController and its subsequent viewControllers rotates as expected but the scrollview doesn't. Its position is fixed.
How can I rotate the container.view i.e scrollbar with buttons along with the navigationController whether using any If statement or defining a separate class for the scrollview.
If you want orientation change event in mainwindow you can use below method in app delegate
- (void)application:(UIApplication *)application willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientation duration:(NSTimeInterval)duration
check also setAutoresizingMask: method and the associated resizing masks.
Related
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 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.
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);
}
?
I am working on an app (my first one), which is basically a TabBar app.
To be more precise there are:
- a login view controller
- a tab bar controller (when login is done)
- a landscape view controller that is used when the first itel of the TabBar is switch from Portrait to Landscape.
So, when I am in the first tab, I need to be able to move to landscape view to display some other data. In my tab bar controller, I have implemented those methods:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if([self selectedIndex] == 0)
return YES;
return NO;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
// Get AppDelegate
MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
// Remove TabBarView and add graph Landscape View
[self.view removeFromSuperview];
[delegate setSubViewLandscapeViewController];
}
}
In the delegate, I have implemented the setSubViewLandscapeViewController and the setSubViewTabBarController:
- (void)setSubViewTabBarViewController {
[window addSubview:[tabBarController view]];
}
- (void)setSubViewGraphLandscapeViewController {
[window addSubview:[landscapeViewController view]];
}
I want the landscapeViewController to display only in landscape mode, I have then (in my landscapeViewController):
- (void)viewWillAppear:(BOOL)animated {
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
NSLog(#"willRotateToInterfaceOrientation");
}
A part of this works fine, I mean the switch from portrait to landscape is ok (when I am in the first tab), the tabbarcontroller is remove from the SuperView and the landscape view is added as a subview instead.
The thing is... I do not know how to switch back to portrait mode (and then load the previous controller, the tabBar one using the setSubViewTabBarViewController of my delegate). It seems none of the willRotateToOrientation, willRotateFromOrientation, .. are triggered when I actually move the device from the landscape view...
In short, when I am in the landscape view I do not know what to do to move back to the tabbar view... I am kind of stuck in the landscape view once I am in this one.
Thanks a lot for your help,
Luc
Look at the pie chart in CPTestApp-iPhone in the examples folder. It handles rotation by implementing -(void)didRotateFromInterfaceOrientation: and resizing the graph after a rotation.
Well, I managed to get a solution for this problem.
In fact, while moving from portrait to landscape I removed the tabbarcontroller from window subview and add the landscapeviewcontroller instead.
It seems it was not the correct thing to do.
Instead, I add the landscapeViewController as subview of the tabbarcontroller and remove it when going from landscape to portrait.
I still have a problem however with the y position of the landscape view which seems to changes when I do several decive rotation in a row....
Regards,
Luc
How can I accomplish the following:
When my app loads a UIView will show 4 buttons
Clicking on a button will load a UITabBarController (not a UIView with a UITabBar) that can display multiple views.
This seems challenging to me, because in order for me to use the UITabBarController I need to add this to the window's subview in my appDelegate. By doing so, my app automatically will load with the UITabbarController in the root view.
You don't need to add the UITabBarController in the application delegate, that's just the most common way to use it. You can have your initial view use a simple UIViewController, then when the button is pressed load the UITabBarController (either programmatically or from a nib), and then display it.
The following is an example of what might be in your app delegate:
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// viewController is a UIViewController loaded from MainWindow.xib with a button that calls loadTabBarController
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
- (IBAction) loadTabBarController {
self.tabBarController = [[[UITabBarController alloc] initWithNibName:#"MyTabBarController" bundle:nil] autorelease];
[viewController.view removeFromSuperview];
[window addSubview:tabBarController.view];
}