I have a UIViewController with IBOutlets linking to several UIViews. Various buttons switch between the views, but there are issues when I set a new view for the controller. Both the controller and the views are in landscape orientation, but after the first couple of switches some of the views display in portrait mode. What might be causing this?
You should check that all your UIViewControllers implement method shouldAutorotateToInterfaceOrientation. This method tells the operation system in what positions (orientations of screen) the UIViews controlled by that UIViewControllers could be displayed.
If you want all your views be displayed only in landscape orientations, then that method should return YES only for interfaceOrintation == UIInterfaceOrientationLandscapeLeft or interfaceOrintation == UIInterfaceOrientationLandscapeRight. if you want only portrait orientations then interfaceOrintation == UIInterfaceOrientationPortrait.
For example (support only landscape modes) :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
And you should check that in your project settings you set appropriate Supported Device Orientations (also known as Supported interface orientations).
I think you should set the views to landscape mode in IB. If this is already done then I would suggest not changing the view controller's view explicitly. Implement a method, which can change the views.
In more detail:
Set a view as your view controller's view then every other view should be the subview of this view. You can make the change by removing the presented view and adding the new view or another method to implement the view changing is to add all view's in IB as a subview, hide all views then when you would like to change unhide the desired one and hide every other.
I hope you understand my approach, if not then I am here to answer your questions.
This way is easy to implement. :)
Check that you have this method enabled in all views:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
Also, is it what you see on the simulator or on your device?
This may be a Simulator bug, but try using separate objects of UIViewController for each view, instead of one controller for all views. Personally, I haven't experienced any difficulty with orientation before, but I do things programmatically. I recommend that you do the same (you may NOT need to convert all your program's xib files, but maybe just the one you're having problems with). Just make sure that all UIViewControllers that you're using for that view to have the:shouldAutorotateToInterfaceOrientation set up appropriately and things should work just fine.
Hope this helps.
Related
supportedInterfaceOrientation should be called only once when viewDidLoad, but in my case it is called every time the simulator rotates.
I need only two orientations potrait and portrait upside down.
when i rotate to upside down the supported interface orientation is called 4 times and my view becomes upside down. on rotation to landscape it is called only once(but it shouldn't ?).
Any solution ?
PS: I am not using any Navigation controller so setting rotation equal to top view controller wont matter. And in my pList only 2 orientations are supported
Also I have a main View Controller in which I add subviews and I have set the supported interface orientation in my view controller.
Weird thing is 3 view controllers that are before(presented before) the faulty one, they
rotate just fine.
You can check the interfaceOrientation in viewDidLoad. You can get the interfaceOrientation with self.userInterFaceOrientation.
Maybe it would be better to check the interfaceOrientation in viewWillAppear.
The difference is, that viewDidLoad will only called one and viewWillAppear every time you enter that view.
Its so Simple you just click on your Project -> Summary -> Supported Interface Orientations. You can click the Interface Orientations as your requirements.
I have a UITabBar application with embedded UINavigation for some of the views. On one specific navigationview I am displaying graphs/charts and it would be better to display them in landscape as if the iPhone was rotated to the left or right. The rest of the app is better suited to portrait. So I want to "force" the views containing graphs to load in landscape regardless of how the user has the device physically rotated. I've tried:
#pragma mark - Rotation
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
But this does not seem to do anything to the view. If I select the "Landscape Left" icon in the "Supported Interface Orientations" for my target then it allows the entire app to re-orientate on rotation of the device. Is there a way to lock my app in portrait for all normal views and lock in landscape for my views containing graphs such that the app ignores the actual device orientation?
You are right. In tab bar applications it is not the shouldAutorotateToInterfaceOrientation: method of the individual view controllers being called. Only the tab bar controller's shouldAutorotateToInterfaceOrientation is called to determine whether and how the views can be oriented.
However, the individual view controllers should implement shouldAutorotateToInterfaceOrientation accordingly anyway. Those methods are still used to determine the orientation of animation effects when pushing or pulling a view controller.
I never tried the following myself: You could try subclassing the tab bar controller and respond to shouldAutorotateToInterfaceOrientation accordingly depending on which view is currently shown to the user. But I fear that Apple has good reasons for forcing us to support the same orientations for all views within a tab bar app.
Firstly I am using iOS 6 SDK.
I am using a custom TabBar Controller.
and controlling the orientation of that TabBar Controller by the below set of codes
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// You do not need this method if you are not supporting earlier iOS Versions
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotate
{
return YES;
}
And the view controller should contain
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
return UIInterfaceOrientationIsLandscape(orientation);
}
This is what I did and was able to lock a view to landscape or portrait (in my case). To force may be you can put a alert view stating the user to turn the device to landscape and show him the graph. Just a suggestion.
Try it in particular ViewController in which you need to required in landscape mode:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight );
}
I am trying to set a UIWindow in MainWindow.xib into landscape mode. Unfortunately, this option is greyed out in Interface Builder. I have a Navigation Controller within the same NIB that can be set to landscape, but this ends up looking awkward in Interface Builder, as the Nav Controller is set to landscape but the containing window is in portrait.
What's worse is that I can't get the window to run in landscape during runtime. I have this code in the view within the nav controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
I don't know how to specify this for the containing window though. I have set the orientation in the plist but this doesn't seem to make my view display in landscape.
From what i can see, it seems like you want your first view controller to be in landscape mode, when displayed.
For this, you need to set the "Initial orientation" in your info.plist file. There is a key for this.
Thus, what you need to do is, Make your xib in landscape mode, implement the method as you have done above and set the initial orientation to landscape in plist.
I faced a problem with the UIWindow being forced into portrait mode as well. My solution was to use another view level between the window and the views I was manipulating. Though not a perfect solution it worked. I hope you get it worked out.
I have an app for the iPad/iPhone and Portrait and Landscape is working just fine. However, I recently added a TabViewController and a second tab with a view. Problem is when I click my second view and rotate and then switch back to the first view my controls are not repositioned
Can anyone tell me what I need to do so that I can reposition my views when the first view is clicked?
incidentally, I am assuming I will have the same problem the other way too... view 2 to view 1.
Did you checked that all your view controller implement this method ?
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
From my experience, the same problem also occurs with navigation controller. I guess that the framework wont send the rotation event to every hidden VC on purpose to save processing time. The solution I ever did is just overriding viewWillAppear and correctly layout subviews there if needed.
a short question.
I've created an app for the iPad, much like a utility app for the iPhone (one mainView, one flipSideView). The animation between them is UIModalTransitionStylePartialCurl.
shouldAutorotateToInterfaceOrientation is returning YES.
If I rotate the device BEFORE entering the FlipSide, everything is okay and the PartialCurl is displayed okay.
But if I enter the FlipSide and then rotate the device, while the UIElements do rotate and position themselves just fine, the actual "page curl" stays with its initial orientation. it just won't budge :)
Is it a known issue? am I doing something wrong?
Thanks!
I too had this issue and somewhat gave up. However, I mentioned my dilemma to a friend, who encouraged me to look into the child VC's logic and I recalled a handy trick that I've used to pass data between parent/child view controllers.
In your flipside view controller, create a "rootViewController" property. In your parent view controller, when you initialize the flipside view controller, you set (where "self" is the rootVC):
flipsideController.rootViewController = self;
You then use this for your flipside VC's shouldAutorotateToInterfaceOrientation method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return interfaceOrientation == self.rootViewController.interfaceOrientation;
}
Viola! The flipside view no longer rotates underneath the partially curled up parent view!
The shortest way of the above code is:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return interfaceOrientation == self.parentViewController.interfaceOrientation;
}