- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationIsPortrait(interfaceOrientation))
{
[self isPortraitSplash];
}
else if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationIsLandscape(interfaceOrientation))
{
[self isLandScapeSplash];
}
return YES;
}
In my methods isPortraitSplash and isLandScapeSplash, i am setting the frames for the view.
When orientation changes, it's always calling isLandScapeSplash - not able to call isPortraitSplash method.
Can any one advise me why this is happening?
Your existing if statement is comparing a BOOL to a UIDeviceOrientation. Your test needs to be:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (UIInterfaceOrientationIsPortrait(interfaceOrientation))
{
[self isPotraitSplash];
}
else if (UIInterfaceOrientationIsLandscape(interfaceOrientation))
{
[self islandScapeSplash];
}
return YES;
}
UIInterfaceOrientationIsPortrait returns a BOOL, so that's all you need in your if statement condition.
Update: I will also add that I agree with the other answers that it's better to do this work in willRotateToInterfaceOrientation:duration:, instead of shouldAutorotateToInterfaceOrientation:.
But, that isn't the reason your original code was failing. The original code was failing because of the if test comparing the UIDeviceOrientation to the BOOL.
Use - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration instead of shouldAutorotateToInterfaceOrientation, it is guaranteed to be called before a rotation occurs.
Do not remove shouldAutorotateToInterfaceOrientation, return YES for every orientation you want to support.
First of all in
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
you have to declare which all orientations you want to support.
and in
- (BOOL)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if (UIInterfaceOrientationIsPortrait(interfaceOrientation))
{
[self isPotraitSplash];
}
else if (UIInterfaceOrientationIsLandscape(interfaceOrientation))
{
[self islandScapeSplash];
}
}
you have to set the frames or any other for layout changes, and use like above.
Related
I Just installed the xcode 11 gm seed and i run my project on it and i realize that non of the rotation method called which were calling perfectly in xcode 10 and before. I don't know is it the bug with xcode or i missing something. Here are device rotation methods i am using
- (BOOL) shouldAutorotate
{
if([videoOptions[#"doc_type"] integerValue] == 3){
return NO;
}
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
if([videoOptions[#"doc_type"] integerValue] == 3){
return UIInterfaceOrientationPortrait;
}
return UIInterfaceOrientationPortrait|UIInterfaceOrientationLandscapeLeft|UIInterfaceOrientationLandscapeRight;
// return UIInterfaceOrientationPortrait;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if([videoOptions[#"doc_type"] integerValue] == 3){
return UIInterfaceOrientationMaskPortrait;
}
return UIInterfaceOrientationMaskAllButUpsideDown;
// return UIInterfaceOrientationMaskPortrait;
}
// Notifies when rotation begins, reaches halfway point and ends.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
// NSLog(#"%ld, duration: %f", (long)toInterfaceOrientation, duration);
// [self.movieSlider hidePopover];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[self viewRotationCompleted];
}
Both methods
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration;
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
are depricated as of iOS8. You need to use their replacement method,
- (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator;
But this method won't be called for UPSideDown rotation. So You need to take care of that.
after browsing through stackoverflow for answers I decided to ask a question.
From my understanding, I'm supposed to override the supportedInterfaceOrientation to handle orientation. For example's sake I implemented it like this
- (NSUInteger)supportedInterfaceOrientations {
if (self.forceLandscape) {
return UIInterfaceOrientationMaskLandscape;
}
return UIInterfaceOrientationMaskPortrait;
}
This lets the controller start in landscape mode when presented and get the forceLandscape ON on default. Then there's a button that will change the orientation on button press
- (IBAction)buttonPress:(id)sender {
self.forceLandscape = !self.forceLandscape;
UIInterfaceOrientation o = UIInterfaceOrientationPortrait;
if (self.forceLandscape) {
o = UIInterfaceOrientationLandscape;
}
[UIApplication sharedApplication].statusBarOrientation = o;
}
Button press would alternatively change between portrait and landscape mode. By setting the status bar orientation it would call the supportedInterfaceOrientations to change the orientation for me. It does call the method and return mask portrait on first button press but it doesn't change the orientation for me. This is the issue I want to fix. Hope that there's a workaround for this.
Replacing the status bar orientation change to this code
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: o] forKey:#"orientation"];
Does call supportedInterfaceMethod and it does change the orientation. However it only work once and that it has access to private code and will be rejected by Apple, which is not desirable.
Not sure that this solution works. In my project (iOS6,7), I fixe the orientation so I don't need to force to change the orientation. However, I found a function in UIViewController that "attemp to rotate the device orientation to the right one
-(BOOL)shouldAutorotate {
FLog(#"");
if (self.forceLandscape) { //force to landscape
return NO;
} else {
return YES; //let's application rotate it self
}
}
-(NSUInteger)supportedInterfaceOrientations {
if (self.forceLandscape) {
return UIInterfaceOrientationMaskLandscapeLeft;
} else {
//You can just allow Portrait.
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskPortrait;
}
}
// Notifies when rotation begins, reaches halfway point and ends.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
//save new orientation
_myOrientation = toInterfaceOrientation;
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
- (IBAction)buttonPress:(id)sender {
self.forceLandscape = !self.forceLandscape;
if (self.forceLandscape) {
_myOrientation = UIInterfaceOrientationMaskLandscapeLeft
} else {
//just do nothing
}
//call this to update orientation
[UIViewController attemptRotationToDeviceOrientation];
}
I check the orientation of the device in viewDidAppear and viewWillAppear and force the orientation by calling willAnimateRotationToInterfaceOrientation method.
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
_levelComplete = YES;
[self willAnimateRotationToInterfaceOrientation:[[UIDevice currentDevice] orientation] duration:0.01];
}
- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == (UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight) )
{
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
{
}
}
The problem i face is that toInterfaceOrientation is remains 0 for both viewDidAppear and viewWillAppear method hence program crashes.
What might be the problem?
Please Help!
Try this
- (void) viewDidLoad
{
_levelComplete = YES;
[self adjustViewsForOrientation:self.interfaceOrientation];
}
-(void) adjustViewsForOrientation:(UIInterfaceOrientation)orientation
{
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
}
else
{
}
}
As you mentioned : The problem i face is that toInterfaceOrientation is remains 0 for both viewDidAppear and viewWillAppear method hence program crashes.
The orientation 0 refers to unknown orientation. Set the break point on viewWillAppear and viewDiddAppear and on orientation delegates. Note that do the delagates of orientation gets called first of the view delegates.
You can use the delegate
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
Using this delegate and the application will be present in Landscape mode or any desired orientation mode.
Try it.
I have started my project with iOS 5.0, Now updated to iOS 6, I am facing problem in doing orientation, To test I have created a sample application, and added the following code in delegate...
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskAll;
}
And in my view controller I have implemented the following methods...
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
-(BOOL)shouldAutorotate
{
return YES;
}
All the above I have done after googled about iOS 6.0,when I load application, based on the option given in supportedInterfaceOrientations view is loading that is fine, now when I changes my device orientations... view is not changing accordingly at run time, how do I change my view based on the device orientation?
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[notificationCenter addObserver:self
selector:#selector(deviceOrientationDidChange)
name:UIDeviceOrientationDidChangeNotification object:nil];
Do I need to add observer like above and changes it programmatically? or Will the view change automatically by detecting device orientation?
try this
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
- (BOOL) shouldAutorotate {
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscape;
}
The previous code should work on iOS6
Anyways, I use this code on one of my projects. I have a boolean _firstTime, and I set it to YES before showing the viewController, then I change it to NO after the viewController appears
- (NSUInteger)supportedInterfaceOrientations {
if (_firstTime) {
return UIInterfaceOrientationMaskLandscape;
} else {
return UIInterfaceOrientationMaskAll;
}
}
- (BOOL) shouldAutorotate {
return YES;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (_firstTime) {
return return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft)||(interfaceOrientation == UIInterfaceOrientationLandscapeRight);
} else {
return YES;
}
}
Change in these method:
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
Note : No need to add observer for device notification.Given below method will specify orientation status
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
EDIT : Provide all your views will automasking according to requirement
EDIT : If using UINavigation Controller then its child View Controller's supportedInterfaceOrientations and shouldAutorotate method will not be called.
Refer this link.
Problem is with my iPad. it has a button to restrict auto rotation change... I was not aware initially, as I was worked fully with iPod.. Thanks all for your helps.
I want to support iOS 6 rotation. Trouble is, I've been looking through a lot of documentation and stack overflow questions but have not found any even slightly in depth solutions. I've only seen that I should add these two methods to my view controller classes - however, if I'm not mistaken, they do not operate in the same way as the pre iOS 6 methods:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll; // use what is appropriate for you.
}
My app currently rotates in pre-iOS6 using the following code. Note that I use the interface orientation parameters to determine whether or not I'm going to push my view Controller. How do I implement this in the iOS 6 rotation delegates?
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
UIInterfaceOrientation toOrientation = self.interfaceOrientation;
if ( self.tabBarController.view.subviews.count >= 2 )
{
UIView *tabBar = [self.tabBarController.view.subviews objectAtIndex:1];
if(toOrientation != UIInterfaceOrientationLandscapeLeft && toOrientation != UIInterfaceOrientationLandscapeRight)
{
CUSTOM_DEBUG_LOG("\n\nRotated back to Portrait");
tabBar.hidden = FALSE;
}
}
}
- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
CUSTOM_DEBUG_LOG("\nView going landscape");
ScrollViewController *s = [[ScrollViewController alloc] initWithNibName:#"ScrollViewController" bundle:nil];
[self.navigationController pushViewController:s animated:NO];
[s release];
self.tabBarController.tabBar.hidden = YES;
self.navigationController.navigationBar.hidden = YES;
}
}
Checkout this and this SO discussion.
[EDIT]
Yes the methods you mentioned aren't deprecated in iOS 6.0 and they will continue working. It's just the way Auto Rotation works have been changed. So far it was view controllers responsibility to decide whether they rotate or not but now RootViewController will decide whether their children should rotate or not. If you don't have rootviewcontroller setup then you have to add it to window and then put shouldAutoRotate and supportedInterfaceOrientations methods in the rootviewcontroller.
Parent Views now handle rotation in iOS 6. Subclass your nav controllers and add a bool
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait; // your rotation here
}
I may not have implemented the iOS6 rotation code correctly when I first posted the question.
I incorrectly thought that the willAnimateRotationToInterfaceOrientation function was deprecated in iOS6, leading me to believe that there was a new iOS rotation delegate with an orientation parameter. Turns out this is not the case, so my app sort of works.
The code I plugged into my app was just this:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
}
If you are using a UINavigationController, override shouldAutomaticallyForwardRotationMethods = YES property.
Then like Mark S said, also override shouldAutorotate and supportedInterfaceOrientations for the children VCs.