iOS - UIViewcontroller detect rotation? - iphone

I am using willRotateToInterfaceOrientation to detect rotation and move items according to the orientation.
The problem is that when the page first loads this method doesn't get called so it doesn't try to move the objects to the correct location?
What is the solution?

You need to setup the interface according to the orientation
if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
// do something
} else if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
// do something else
}
And repeat that for al the different device orientations

I manually detected the UIInterfaceOrientation from my UIApplication, and I manually called willAnimateRotationToInterfaceOrientation on viewDidAppear

Related

UIImagePickerController interfaceOrientation always come up as portrit

I am trying to capture the current orientation of the UIImagePickerController being presented, and changing the overlay view's hidden property accordingly.
if([notification.name isEqualToString:#"UIDeviceOrientationDidChangeNotification"]) {
UIInterfaceOrientation orientation = self.cameraImagePicker.interfaceOrientation;
if(orientation == UIInterfaceOrientationPortrait) {
self.cameraImagePicker.cameraOverlayView.hidden = NO;
} else {
self.cameraImagePicker.cameraOverlayView.hidden = YES;
}
}
However, orientation == UIInterfaceOrientationPortrait even if I rotate the camera, but this method is called every time the device rotates.
Note: My application only supports portrait orientation according to the project file, but rotation is somehow still supported by the UIImagePickerController
Any help with this issue would be greatly appreciated!
After iOS6, apple changed the orientation API. you can try this method in your appdelegate, I hope it can help you.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}

How to allow only particular view to rotate? (iPhone)

I am installing AdMob's ad, and there is a GADBannerView.
After installing, a banner show, and if you click on it, a page will slide out coving the whole screen, and displaying advertising contents in it.
The question is, some advertising contents, such as video, had to be played landscape. However, I don't want other part of my application to rotate, as the app is not designed to be viewed in landscape.
So, how can I implement something which can achieve such function?
Try to use Notification for this. a notification calls a selector every time when ur device orientation is changed.
write this in your viewDidLoad:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(setScreenWithDeviceOrientation:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
and then define the selector as follows:
-(void)setScreenWithDeviceOrientation:(NSNotification *)notification
{
UIDeviceOrientation orientation=[[UIDevice currentDevice] orientation];
if(orientation==UIInterfaceOrientationPortrait) //Portrait orientation
{
// setView frame for portrait mode
}
else if(orientation==UIInterfaceOrientationPortraitUpsideDown) // PortraitUpsideDown
{
// setView frame for upside down portrait mode
}
else if(orientation==UIInterfaceOrientationLandscapeLeft)
{
// setView frame for Landscape Left mode
}
else if(orientation==UIInterfaceOrientationLandscapeRight) //landscape Right
{
// setView frame for Landscape Right mode
}
else
{
NSLog(#"No Orientation");
}
}
this method fired everytime when ur device changes orientation. Based on the current orientation you should adjust your view.
I hope this will help you.
Are you working with iOS 6? You should be able to just restrict what orientations your view controller handles in this case. For example, in your view controller that handles your GADBannerView, you can just put:
// Tell the system what we support
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
// Tell the system It should autorotate
- (BOOL) shouldAutorotate {
return NO;
}
// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
And that should make it so that your viewcontroller only supports portrait.
Have you looked at this question and answer? This explains how a single view can work in a certain orientation that is not supported by the rest of the application:
AutoRotate ONLY MpMoviePlayerControler iOS 6

how to know the device orientation correctly

I want to know the device orientation when user start my app , in order to produce different view. What I find strange is as below:
- (void)viewDidLoad
{
if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
NSLog(#"1");
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
NSLog(#"2");
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft) {
NSLog(#"3");
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown) {
NSLog(#"4");
}
}
No one is printed! I did it on the ipad simulator and I think the orientation should be UIDeviceOrientationPortrait. Why this happen? and how to know the orientation correctly?
Try to use
[UIApplication sharedApplication].statusBarOrientation
instead of
[UIDevice currentDevice].orientation
It may be the case that the simulator simply cannot be in an orientation state (it makes no sense, as you can't really rotate your computer...) Have you checked whether it returns UIDeviceOrientationUnknown?
The documentation or UIDevice states:
You get the current orientation using the orientation property or
receive change notifications by registering for the
UIDeviceOrientationDidChangeNotification notification. Before using
either of these techniques to get orientation data, you must enable
data delivery using the beginGeneratingDeviceOrientationNotifications
method
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html
So it is probably that you get Unkown orientation because you never started the orientation notifications generation.
You should also log the value in your viewDidLoad to confirm exactly what you receive when you get the orientation. That would be a good starting point for further investigation.
Use this :-
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
//code for portrait
}
else
{ //code for Landscape
}
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationPortrait ||interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation is the delegate method oa uiviewcontroller.
According to the docs, the orientation property of UIDevice will always return 0 (i.e., UIDeviceOrientationUnknown) unless -beginGeneratingDeviceOrientationNotifications has been called first. This method will enable the accelerometer, deliver notification changes, and update the orientation property of the UIDevice singleton.

Hide UIView on device rotation - doesn't work when device is horizontal

I'm trying to hide an image in a view controller when the device is rotated. I'm posting a notification in PlayerViewController and am listening for it in the app delegate, which is responsible for the bannerView:
- (void)orientationChanged:(NSNotification *)notification {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if ((orientation == UIDeviceOrientationLandscapeLeft) ||
(orientation == UIDeviceOrientationLandscapeRight)) {
bannerView.hidden = ([[self.navigationController visibleViewController] isKindOfClass:[PlayerViewController class]]) ? YES : NO;
} else {
bannerView.hidden = NO;
}
}
The PlayerViewController sends a notification and the app delegate hides the bannerView. However, when the device is laid flat on a table, the image shows. Works fine when the device is held vertically but horizontally the image appears... odd.
Here is the code to send the notification:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
... hide other stuff in this view controller
}
Any ideas why this odd behavior is occurring?
Just one tidbit more information. In the simulator the image shows when the device is in upside-down orientation, even though I have:
- (BOOL)shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIDeviceOrientationPortrait) {
return YES;
} else {
return NO;
}
}
Your error might be happening because of when you're posting the notification.
willAnimateRotationToInterfaceOrientation is called before the orientation change takes place (hence the "will" in the method name). So if we're going from portrait to landscape, the current orientation may still be reported as portrait (it may not, it depends).
Now, the willAnimate... call returns the toInterfaceOrientation - the orientation that is going to happen.
You trigger your notification when you receive the willAnimate... call, and inside that notification call [[UIDevice currentDevice]orientation]: which will return portrait. Instead of requesting the orientation in your notification method you should instead pass the orientation provided in the willAnimate call.
If that wasn't clear, the one sentence summary: willAnimateRotationToInterfaceOrientation is called before the rotation changes.

Handle orientation when showing a view

I have a few changes that get made to a UIView when the orientation changes. This works fine. The problem arises when adding the view after the phones orientation is already switched. This causes none of the rotate methods to be called and therefor does not give me the opportunity to make changes.
What would be the correct way of handling this, probably in ViewDidLoad? Would I be able to detect the current orientation at that point?
Bare in mind that its a few minor changes that I would need to make, so I dont want to load a different nib or anything like that
Thanks you very much :)
EDIT* just to clear things up: As I mentioned, the view is not even instantiated yet when the device orientation changes. The orientation changes to landscape -> the user clicks a button that shows another view -> this new view gets created and shown, but its default positioning is for portrait orientation -> when the view is shown, the elements I rearrange in the willAnimateRotationToInterfaceOrientation method are in the wrong position.
Typically I put the animations that occur when the user rotates the device (manipulating the frames of views mostly) in the willAnimateToInterfaceOrientation method. In it's skeleton form it would look like this:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
//NSLog(#"willAnimateRotationToInterfaceOrientation: %d", toInterfaceOrientation);
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation))
{
// portrait
}
else
{
// landscape
}
}
EDIT: In situations where I need to remember the device rotation for future use, I set up an ivar in my view controller class called currentOrientation (type int), and then do this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
//NSLog(#"shouldAutorotateToInterfaceOrientation: %d", toInterfaceOrientation);
if (toInterfaceOrientation == UIDeviceOrientationPortrait || toInterfaceOrientation == UIDeviceOrientationPortraitUpsideDown ||
toInterfaceOrientation == UIDeviceOrientationLandscapeLeft || toInterfaceOrientation == UIDeviceOrientationLandscapeRight)
{
currentOrientation = toInterfaceOrientation;
}
return YES;
}
Then while running the methods in the view controller, I know which orientation the device is in.