for the query of methods of rotation - iphone

I have 1 UIViewController.
in that i wrote,
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
NSLog(#"A");
} in UIViewController.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
NSLog(#"b");
}
but this method is not called
why is it so?

You may need to do two things:
Tell device to track orientation changes: call [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
Implement your View controllers -shouldAutorotateToInterfaceOrientation method - return YES for orientations you want to support.

Related

Orientation should change only for the selected viewcontroller

In my app, Four viewcontrollers navigates next by next in potrait mode, but i added coverflow in the final viewcontroller, and when the simulator is rotated it should go landscape.I selected all orientations in plist execpt the Upsidedown orientation, So that coverflow works fine in Landscape, but all the other viewcontrollers also goes to landscape when rotatad, but i need these viewcontrollers to be in potrait even the simulator is rotated.I tried many codes like,
shouldAutorotate and supportedInterfaceOrientations.
But i doesn't get a clear solution towards what iam expecting, if any ideas , will be thankfull.
Add an observer to the viewDidLoad method of the view you want to rotate like this :
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
and then set the views according the the landscape view inside the orientationChanged method like this :
- (void) orientationChanged:(NSNotification *)note{
UIDevice * device = [UIDevice currentDevice];
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
break;
case UIDeviceOrientationLandscapeLeft:
break;
case UIDeviceOrientationLandscapeRight:
break;
default:
break;
};
}
Add new Objective-C class (subclass of UINavigationController) and add the following code to the .m files
-(NSUInteger)supportedInterfaceOrientations
{
NSLog(#"supportedInterfaceOrientations = %d ", [self.topViewController supportedInterfaceOrientations]);
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// You do not need this method if you are not supporting earlier iOS Versions
return [self.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
After you added the new classes go to your ViewController classes and make the following changes
- (BOOL)shouldAutorotate // iOS 6 autorotation fix
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations // iOS 6 autorotation fix
{
return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation // iOS 6 autorotation fix
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
In the shouldAutorotate , shouldAutorotateToInterfaceOrientation: return YES if you want the ViewController to be supporting Multiple orientation else return NO , also in houldAutorotateToInterfaceOrientation: method pass the Orintation you want for that specific ViewController , Repeat the same for all the view controllers .
Reason of doing this:-
1:Although you can change the preferredInterfaceOrientationForPresentation: of any viewController to a specific orientation but since you are using the UINavigationController you also need to override the supportedInterfaceOrientations for your UINavigationController
2:In order the override the supportedInterfaceOrientations for UINavigationController we have subclassed UINavigationController and modified the method related to the UINavigation Orientation.
Hope it will help you !
In iOS 6 and later, the view controllers responsible for rotation are the container Viewcontrollers such as UINavigationController & UITabBarController . What are you using as the rootviewcontroller in your project??
I have navigation controller category written here in which you can handle the supported interface orientations for the individual view controllers.
viewDidLoad or viewWillApper method add following code
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
set the orientation
#if (__IPHONE_6_0 >= __IPHONE_OS_VERSION_MAX_ALLOWED)
- (NSInteger)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortraitUpsideDown | UIInterfaceOrientationMaskPortrait);
}
#endif
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation==UIInterfaceOrientationPortrait);
}

UIDeviceOrientationDidChangeNotification is returning UIOrientationLandscapeLeft for UIOrientationLandscapeRight

I am registering my viewcontroller for UIDeviceOrientationDidChangeNotification and it's return wrong orientation of device.
I am registering it in init function of viewcontroller
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(handleOrientationChangeNotification:) name: UIDeviceOrientationDidChangeNotification object: nil];
This is my device Notification Receiver method.
-(void)handleOrientationChangeNotification:(NSNotification *)notification
{
if(IS_IPHONE)
{
UIDeviceOrientation currentDeviceOrientation = [[UIDevice currentDevice] orientation];
.
.
.
}
Whenever Device Orientation changed,I am always getting wrong orientation.
I find the solution on apple site on this link
UIDeviceOrientationLandscapeRight is assigned to UIInterfaceOrientationLandscapeLeft and UIDeviceOrientationLandscapeLeft is assigned to UIInterfaceOrientationLandscapeRight. the reason for this is that rotating the device requires rotating the content in the opposite direction.
This is Probably happening because Apple Has changed the Way of managing the Orientation of UIViewController.
In Ios6 Oreintation handles Differently, in iOS6 shouldAutorotateToInterfaceOrientation method has deprecated.iOS containers (such as UINavigationController) do not consult their children to determine whether they should autorotate. By default, an app and a view controller’s supported interface orientations are set to UIInterfaceOrientationMaskAll for the iPad idiom and UIInterfaceOrientationMaskAllButUpsideDown for the iPhone idiom.
For More Information regarding the same You should visit this link
Below I have made the Category for handling the Orientation Change.
SO You will have to implement the Two more methods for managing the Orientation of UIViewController in iOS6.
Introduced In IOS6 Allow Orientation Change
- (BOOL)shouldAutorotate
{
return YES;
}
Return the Number of Oreintation going to supported in device
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
Now check what orientation you are getting.
EDIT: Place this Code to your FirstViewController added as root ViewController .this will help the UIViewController to determine it's Orientation.
#implementation UINavigationController (RotationIn_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
I hope i'll be helpful to you.

When to use layoutSubview in iOS

I am writing iOS application for iPad that require custom layout.
The layout from portrait and landscape are totally difference, so it can't be solve by using UIAutoResizingMask.
I try to use the layoutSubview Method, but I detected that layout subview is called a lot (from UIScrollView).
How can i reduce the layoutSubview call to optimize the code , or I should call it by my self when ever the device is rotated.
Thank.
For different landscape and portrait design use view controllers methods such as
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
If you create your custom view depending on current orientation, check this orientation by UIDeviceOrientationDidChangeNotification notification and write appropriate code.
in one of the init~ methods:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didChangedOrientation:) name:UIDeviceOrientationDidChangeNotification object:nil];
And action
- (void) didChangedOrientation:(NSNotification *)sender{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (UIDeviceOrientationIsPortrait(orientation)){}}
The fact that layoutSubviews gets called by a child UIScrollView is very unfortunate, but there's an (ugly) workaround:
#interface MyClass : UIView {
BOOL reallyNeedsLayout_;
}
#end
#implementation MyClass
- (void)setNeedsLayout
{
[super setNeedLayout];
reallyNeedsLayout_ = YES;
}
- (void)setFrame:(CGRect)rect
{
[super setFrame:rect];
reallyNeedsLayout_ = YES;
}
- (void)layoutSubviews
{
if (!reallyNeedsLayout_) return;
reallyNeedsLayout_ = NO;
// Do layouting.
}
#end
Not the best solution but seems to work reasonably well.
You should not do expensive calculations in layoutSubviews:
Speaking from experience I would personally only adjust your layout based upon deviceDidRotateSelector notifications.
I have an updatePortrait method and an updateLandscape method and call whichever is necessary.

UIInterfaceOrientation method not working

Call is not going into the UIInterfaceOrientation delegate method please help
here is the code
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
{
NSLog(#"potrait");
}
else
{
}
}
Is your view controller inside another view controller?
Look for Technical Q&A QA1688 Why won't my UIViewController rotate with the device? in your developer documentation
That will give you a hint of why it isn't working in your case.
I had this problem last week, and here is what I discovered. If you are using a tab bar, then you must have
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
in every view controller that is added to the TabBarController in order for any of them to rotate. If you only want certain tabs to rotate, you can still achieve this by adding
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
}
There may be a similar resolution if you are using a NavigationController, but I haven't run in to that problem yet.

ViewController not responding to didRotateFromInterfaceOrientation

My view controller is not responding to didRotateFromInterfaceOrientation, despite that I have added following in my code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
[self.popOver dismissPopoverAnimated:NO];
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
... My Custom Code...
}
}
Am I doing something wrong here?
If you can't inherit from UIViewController (which is unfortunate), you can use this:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
Then register to start receiving UIDeviceOrientationDidChangeNotification notifications.
If your UIViewController is a child in some root view then IB does not add it as a child controller to the root controller by default. The easiest way to address this is to modify your root controller:
- (void)viewDidLoad
{
[super viewDidLoad];
[self addChildViewController:(UIViewController*) self.yourChildController];
}
This should do the trick. Now your child controller will be receiving both:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
and
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
messages.
I think the real answer here (more accurately the answer to the linked question) is that you need to call
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
in your subclass implementation of the didRotateFromInterfaceOrientation method. For example:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
// Then your code...
}
This is not mentioned in the apple documentation but caused some serious and unexplained problems for me when omitted...