Camera App Supported Orientation? - iphone

I want to do the same as Camera app: it looks like only Portrait mode is supported but when you rotate certain views get rotated while toolbar and some controls are in the same place.
I tried to disable all supported orientation in PLIST file but this calls no delegate method such as shouldRotate, or, obviously, willRotate to perform orientation change.
When supported orientation are in PLIST, iPhone rotates all views, even though I return NO for shouldRotate method.
How to solve such dilemma?

In the info.plist, set the only supported orientation to Portrait. Then, in you viewDidLoad method, add:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
This will call the method:
- (void)didRotate:(NSNotification *)aNotification; {
UIDeviceOrientation currentDeviceOrientation = [[UIDevice currentDevice] orientation];
switch(currentDeviceOrientation){
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
break;
case UIDeviceOrientationLandscapeLeft:
break;
case UIDeviceOrientationLandscapeRight:
break;
default:
break;
}
}
From there, you can do whatever you want based on any option. Also, don't forget to add this:
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
To you dealloc method. Hope that Helps!

Related

How to achieve this in iOS?

I am referring to DMD Panorama app.
As you can see there is a Yin-yang symbol at the top section of this image.
Once we rotate our device, the two symbols come closer, like below:
Can you please let me know how do I detect rotation of the device so that when device is rotated, these two images come closer?
I appreciate your response.
Add a notifier in the viewWillAppear function
-(void)viewWillAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];}
The orientation change notifies this function
- (void)orientationChanged:(NSNotification *)notification{
[self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];}
which in-turn calls this function where the moviePlayerController frame is orientation is handled
- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
//load the portrait view
}
else if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
//load the landscape view
}}
in viewDidDisappear remove the notification
-(void)viewDidDisappear:(BOOL)animated{
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];}
first you register for notification
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(detectDeviceOrientation) name:UIDeviceOrientationDidChangeNotification object:nil];
then add this method
-(void) detectDeviceOrientation
{
if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) ||
([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight))
{
// Landscape mode
} else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait)
{
// portrait mode
}
}
Try doing the following when the application loads or when your view loads:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
Then add the following method:
- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
/* set frames for images */
break;
case UIDeviceOrientationPortraitUpsideDown:
/* set frames for images */
break;
default:
break;
};
}
The above will allow you to register for orientation changes of the device without enabling the autorotate of your view.

Detecting iOS orientation change instantly

I have a game in which the orientation of the device affects the state of the game. The user must quickly switch between Landscape, Portrait, and Reverse Landscape orientations. So far I've been registering the game for orientation notifications via:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
But it is far too slow - there seems to be about a second delay between rotating the phone and the notification actually being fired. I need a way to INSTANTLY detect changes in the device's orientation. I have tried experimenting with the gyroscope, but am not yet familiar enough with it to know whether or not it is the solution I am looking for.
Add a notifier in the viewWillAppear function
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
The orientation change notifies this function
- (void)orientationChanged:(NSNotification *)notification{
[self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}
which in-turn calls this function where the moviePlayerController frame is orientation is handled
- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {
switch (orientation)
{
case UIInterfaceOrientationPortrait:
case UIInterfaceOrientationPortraitUpsideDown:
{
//load the portrait view
}
break;
case UIInterfaceOrientationLandscapeLeft:
case UIInterfaceOrientationLandscapeRight:
{
//load the landscape view
}
break;
case UIInterfaceOrientationUnknown:break;
}
}
in viewDidDisappear remove the notification
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}
I guess this is the fastest u can have changed the view as per orientation
That delay you're talking about is actually a filter to prevent false (unwanted) orientation change notifications.
For instant recognition of device orientation change you're just gonna have to monitor the accelerometer yourself.
Accelerometer measures acceleration (gravity included) in all 3 axes so you shouldn't have any problems in figuring out the actual orientation.
Some code to start working with accelerometer can be found here:
How to make an iPhone App – Part 5: The Accelerometer
And this nice blog covers the math part:
Using the Accelerometer
Why you didn`t use
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
?
Or you can use this
-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
Or this
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
Hope it owl be useful )
For my case handling UIDeviceOrientationDidChangeNotification was not good solution as it is called more frequent and UIDeviceOrientation is not always equal to UIInterfaceOrientation because of (FaceDown, FaceUp).
I handle it using UIApplicationDidChangeStatusBarOrientationNotification:
//To add the notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didChangeOrientation:)
//to remove the
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
...
- (void)didChangeOrientation:(NSNotification *)notification
{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsLandscape(orientation)) {
NSLog(#"Landscape");
}
else {
NSLog(#"Portrait");
}
}
Try making your changes in:
- (void) viewWillLayoutSubviews {}
The code will run at every orientation change as the subviews get laid out again.
#vimal answer did not provide solution for me. It seems the orientation is not the current orientation, but from previous orientation. To fix it, I use [[UIDevice currentDevice] orientation]
- (void)orientationChanged:(NSNotification *)notification{
[self adjustViewsForOrientation:[[UIDevice currentDevice] orientation]];
}
Then
- (void) adjustViewsForOrientation:(UIDeviceOrientation) orientation { ... }
With this code I get the current orientation position.

populate entire landscape screen with new uiview upon device orientation change from portrait to landscape

So my iPhone application currently has a tabviewcontroller that populates the entire screen. The app only runs in portrait mode. My task has been to detect device orientation changes, and once it changes to landscape, have a new uiview populate the entire screen.
I already have the device orientation change detection working. I've used an NSNotificationCenter to successfully call a helper method, deviceOrientationChanged, once an orientation change is detected. IF the change was to landscape mode, I run a certain block of code.
In this block of code I have already tried various things, none of which are successful. Simply saying self.view = newViewThing; does not work because the statusbar is still present at the top and the tabs are still present at the bottom.
I have also tried adding this newViewThing as a subview to the UIWindow. This did not work because while the view was added, it was not oriented correctly.
THE QUESTION IS: is there a way to load an entirely new uiview once a device orientation change is detected? Thank you in advance.
Yes, there is a way to load a new view. I make it in my app that way:
- (void)orientationChanged:(NSNotification *)notification
{
// We must add a delay here, otherwise we'll swap in the new view
// too quickly and we'll get an animation glitch
[self performSelector:#selector(updateLandscapeView) withObject:nil afterDelay:0];
}
- (void)updateLandscapeView
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
[self presentModalViewController:self.landscapeView animated:YES];
isShowingLandscapeView = YES;
}
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
[self dismissModalViewControllerAnimated:YES];
isShowingLandscapeView = NO;
}
}
And also I have added this code to viewDidLoad:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification object:nil];
and this code to dealloc:
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];

iPhone center activity indicator regardless of screen orientation

How can I center an activity indicator programmatically regardless of screen orientation?
Try setting the center property of your activity view, like this:
activity.center = CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/2);
In viewDidLoad, register for notifications for the device rotation:
- (void)viewDidLoad {
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:UIDeviceOrientationDidChangeNotification object:nil];
}
and implement didRotate:
-(void)didRotate:(NSNotification *)notification {
if (activity) {
activity.center = CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/2);
}
}
I suggest you use https://github.com/jdg/MBProgressHUD
Which is a great library for doing all kinds of "Loading" screens.

How to subscribe self on the event of Device Orientation(not interface orientation)?

in my app i want to call some method in CCScene myscene in the case of device rotation(orientation change).I disabled the autorotation(because i want it not to happen).
The issue is: i want to change gravity in the scene depending on my device orientation.
My code :
-(void) onEnter
{
[super onEnter];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notification_OrientationWillChange:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notification_OrientationDidChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}
-(void) onExit
{
//[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
//[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}
-(void)notification_OrientationWillChange:(NSNotification*)n
{
orientation = (UIInterfaceOrientation)[[n.userInfo objectForKey:UIApplicationStatusBarOrientationUserInfoKey] intValue];
}
-(void)notification_OrientationDidChange:(NSNotification*)n
{
if (orientation == UIInterfaceOrientationLandscapeLeft) {
b2Vec2 gravity( 0, -10);
world->SetGravity(gravity);
}
if (orientation == UIInterfaceOrientationLandscapeRight) {
b2Vec2 gravity( 0, 10);
world->SetGravity(gravity);
}
}
But in this case i can get notifications only in the case of autorotation enabled.(if it disabled, device is actually don't change it status bar orientation)
Can you help me?
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:#"UIDeviceOrientationDidChangeNotification"
object:nil];
- (void)orientationChanged:(NSNotification *)notification{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
//do stuff
NSLog(#"Orientation changed");
}
You must check for Device orientation not status bar.
typedef enum {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait, // Device oriented vertically, home button on the bottom
UIDeviceOrientationPortraitUpsideDown, // Device oriented vertically, home button on the top
UIDeviceOrientationLandscapeLeft, // Device oriented horizontally, home button on the right
UIDeviceOrientationLandscapeRight, // Device oriented horizontally, home button on the left
UIDeviceOrientationFaceUp, // Device oriented flat, face up
UIDeviceOrientationFaceDown // Device oriented flat, face down
} UIDeviceOrientation;