I have four controllers for the tab bar and it's views, when I rotate phone I want it to call the method shouldAutorotateToInterfaceOrientation for only one of the controllers but it calls the method for all of them.
How can I call shouldAutorotateToInterfaceOrientation for only one of the controllers?
You don't "call" these methods, those are methods that are being called for any class that inherits from UIViewController.
There is no reason to want them not to be called anyway.
What you can do is decide to override any of these methods for any of your controller.
The method returns a boolean, if you return true, then the view is being rotated, if you return false, then it is not.
You can also decide to return YES/NO based on the orientation, in order to support one specific orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
In this case, the view is being rotated only if the new orientation is portrait.
Thank you JP Hribovsek, I solved it using beginGeneratingDeviceOrientationNotifications that notifies me when the device´s orientation is changed. For example:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(deviceRotate:)
name: UIDeviceOrientationDidChangeNotification
object: nil];
-(void) deviceRotate: (NSNotification*) notification
{
UIDeviceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSlog(#"Landscape");
}
}
Related
I have an app that is portait mode only. I only have one View Controller that I need to force into landscape mode (A customer signature view) so there is more room for the customer to sign.
How can I force one ViewController to appear in landscape mode. Leaving the rest in portrait?
I have tried setting the app's General Deployment info to Portrait, Landscape Left
And then using this code on the Signature View
- (BOOL)shouldAutorotate {
return YES;
}
and returning NO on all other view controllers. But that didn't seem to work.
I also included
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
Is this possible?
Try this code in the Signature View Controller
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeLeft] forKey:#"orientation"];
}
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:#"orientation"];
}
You're just missing the following code below, if your UIViewController is a rootcontroller of a navigationcontroller you need to put the code in the navigationcontroller. Hope this helps, good luck.
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
Following is the the way its working for me:-
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft;
}
and
- (BOOL)shouldAutorotate {
return NO;
}
Another way is to define orientation in prepareForSegue and fixed orientation of the required VC and set shouldAutorotate to NO in that VC.
Let me know if mentioned code doesn't work for you.
I have a controller which should be rotated with interface (device) orientation change. I track orientation changes, however i'm unable to rotate the view with the device orintation changes.
I can animate the views inside, and switch their constraints etc, but i'd like to use Size classes for that. When i switch to UIModalPresentationStyleCurrentContext on presenting the controller it works, but messes with my navigation and tabbar, and i would like to do it this way.
Can it be done this way?
Ok, solved it.
I track device orientation changes by putting this in viewDidLoad of the controller which needs to change orientation:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:#"UIDeviceOrientationDidChangeNotification"
object:nil];
Then in orientationChanged:
- (void)orientationChanged:(NSNotification *)notification{
[RecorderViewController attemptRotationToDeviceOrientation];
}
In order for that to work in the parent controller i added these :
-(BOOL) shouldAutorotate {
return true;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
Also, for rotation to work recorder controller has to implement these:
- (BOOL)shouldAutorotate {
return true;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
Hopefully somebody finds this useful.
I have been looking into ways of setting up separate landscape and portrait view controllers to handle a changing orientation. The code posted below is from Apple stating how to do this. I noticed they use performSegueWithIdentifier. It seems odd that a segue is being used.
In order to create a segue on the storyboard I'm assuming I must create a hidden button and drag the connection from the portrait to the landscape view controller. I can then set the segue identifier to "DisplayAlternateView". What is the default segue animation? Or is the default to turn the animation off?
Also why is this code in the awakeFromNib method? Shouldn't it be in viewDidLoad? Is awakeFromNib called before viewDidLoad?
Also I'm assuming I must have a different target action for every scene of my storyboard. If I have portrait view A, B and C with a corresponding landscape view A, B and C, should I have the following changes to the Apple code
on my A view:
selector:#selector(orientationChangedA:)
then on my B
selector:#selector(orientationChangedB:)
then on my C
selector:#selector(orientationChangedC:)
This way each method can perform it's own segue.
I feel like I might be over complicating things here. Are the separate segues causing me to do extra work or is this how how orientation switching to separate view controllers normally handled?
Here is the code from Apple saying how to handle orientation changes with different view controllers:
#implementation PortraitViewController
- (void)awakeFromNib
{
isShowingLandscapeView = NO;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!isShowingLandscapeView)
{
[self performSegueWithIdentifier:#"DisplayAlternateView" sender:self];
isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
isShowingLandscapeView)
{
[self dismissViewControllerAnimated:YES completion:nil];
isShowingLandscapeView = NO;
}
}
I need a view that can display both in Portrait and landscape.But when I load another view I only want it show in landscape.
I have a view controller A.which can be shown in portrait and landscape.This view controller is create by the App delegate.
When I click a button on the view A.I create a view controller B which I want to display only in landscape.and load the view like [A.view addSubView:B.view].
When I rotate the device the function shouldAutorotateToInterfaceOrientation is called only in
controller A. No matter how I set the function in controller B.It can't be called.
On your first view, make sure that
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
return Yes;
}
And in your second view set it to
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
Update:
Ok, try this...
In your main view controller/app delegate, where the shouldAutorotateToInterfaceOrientation is run every time the device rotates, put a global level variable. something like
.h
#interface NavAppDelegate : NSObject <UIApplicationDelegate> {
Bool *isMain;
}
.m
-(void)viewDidLoad {
isMain = Yes;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
if (isMain) {
return Yes;
} else {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
}
// This bit is where you'll have to adapt it to how you change your views
// but it's a basic idea.
-(void)bitThatDoesTheViewChange:(viewController *) controller {
isMain = No;
*viewController = controller;
[viewController release];
isMain = Yes;
}
Excuse my English.. :)
In my viewController (A) there is a orientation notifier like this:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{ UIDeviceOrientation newOrientation = [[UIDevice currentDevice] orientation];
if (newOrientation == UIDeviceOrientationUnknown || newOrientation == UIDeviceOrientationFaceUp || newOrientation == UIDeviceOrientationFaceDown) {
UIInterfaceOrientation mainOrientation = [[UIApplication sharedApplication] statusBarOrientation];
newOrientation = (UIDeviceOrientation) mainOrientation;
}
This is working properly when this is the controller.
There is a ModalViewController (B) that sometimes appear, and this could be reoriented to new orientation, and do it perfect. BUT, when this modal is dismissed, the main view controller remains in the same orientation it was before.
Controlling by breakpoints I´ve checked that the code in the method above is not being executed.
All this has been working perfectly before I actualized IOS5 SDK.
(I´ve not refactoriced to ARC, because of CGPLOT issues).
Any one could help me, or has suffered same issue?
The obvious solution is to call this method from the modal view... but it´s annoying..:(
Thanks you very much and have a nice day!
Send a notification using
[[NSNotificationCenter defaultCenter] postNotificationName:#"changeOrientation" object:nil];
from view where didRotate... worked and in other class use:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doWork) name:#"changeOrientation" object:nil];
to catch this event.
Лайтбрингер с ЕГ-форума?