change custom label and button to landscape in xcode 5 - ios

i create a custom button and label in portrait mode and landscape mode separately as below:
- (BOOL)shouldAutorotate {
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait) {
[self addButton1];
[self addLabel1];
}
else if(orientation == UIInterfaceOrientationLandscapeRight)
{
[self addButton2];
[self addLabel2];
}
return YES;
}
if i run this code,in landscape mode both buttons and labels are displayed.
if i try this:
else if(orientation == UIInterfaceOrientationLandscapeRight)
{
[self addButton2];
[self addLabel2];
[custombtn1 setHidden:YES];
}
error:use of undeclared identifier.
can somebody help me?

You need to implement the method:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
This method is called regardless of whether your code performs one-step or two-step rotations.
Parameters
fromInterfaceOrientation
The old orientation of the user interface. For possible values, see UIInterfaceOrientation.
Additionally, you could hide unnecessary buttons.
addButton2.hidden = YES;

Related

Device Orientation not getting.

Currently i am working on IOS 7 and my problem is i am not able to get orientation of current device in ViewDidLoad method.
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskAll);
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
NSLog(#"i am in landscape mode");
}
if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)){
NSLog(#"i am in portrait mode");
}
}
I write this code in my FirstViewController.m,and when i run my application no condition become true out of them,
can anybody help me why no condition become true even i run my application in portrait mode.
Thanks in advance.
Try this.
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsLandscape(orientation)) {
//Landscape mode
}
else
{
//Portrait mode
}
EDIT : Use UIInterfaceOrientationIsLandscape and UIInterfaceOrientationIsPortrait method to find orientation mode
try this
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIDeviceOrientationIsLandscape(orientation))
{
NSLog(#"i am in landscape mode");
}
if (UIDeviceOrientationIsPortrait(orientation)){
NSLog(#"i am in portrait mode");
}
oky u hav other orientation call back methods this one called before rotation is going to occur - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration and this one just after second one - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation, for example
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
UIInterfaceOrientation orientation = toInterfaceOrientation; //hear toInterfaceOrientation contains the which orientation is device is turning to
if (UIDeviceOrientationIsLandscape(orientation))
{
NSLog(#"i am in landscape mode");
}
if (UIDeviceOrientationIsPortrait(orientation)){
NSLog(#"i am in portrait mode");
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
UIInterfaceOrientation orientation = fromInterfaceOrientation; // hear fromInterfaceOrientation contains previous state of the orientation
if (UIDeviceOrientationIsLandscape(orientation))
{
NSLog(#"i am in landscape mode");
}
if (UIDeviceOrientationIsPortrait(orientation)){
NSLog(#"i am in portrait mode");
}
}
for more information see docs
hope this helps u .. :)

Use camera in Landscape only app -iOS

I have an application that supports only landscape mode. When I opening the camera the app crashes. I solved the problem by using the following code.
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
-(BOOL)shouldAutorotate {
return [[UIDevice currentDevice] orientation] != UIInterfaceOrientationPortrait;
}
But the app turns to support all orientations. All I want is the app only support landscape mode and also uses camera.
Any help will be appreciated.
I finally figured it out. The shouldAutorotate never gets called in ViewControllers. Because the topmost view controller has to return the interface orientations it wants to rotate to. In my case, that's the UINavigationController. So I creates the new category for UINavigationController to make it work. I uses the following methods in the category
#implementation UINavigationController (BugiOSFix)
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
-(BOOL)shouldAutorotate {
return [[UIDevice currentDevice] orientation] != UIInterfaceOrientationPortrait;
}
#end
Write this For orientations .........
-(void)viewWillAppear:(BOOL)animated
{
[self willAnimateRotationToInterfaceOrientation:
[UIApplication sharedApplication].statusBarOrientation duration:1.0];
UIInterfaceOrientation orientation =
[UIApplication sharedApplication].statusBarOrientation;
if(orientation == UIInterfaceOrientationLandscapeRight ||
orientation == UIInterfaceOrientationLandscapeLeft)
{
[self setFrameForLeftAndRightOrientation];
}
else if(orientation == UIInterfaceOrientationPortrait )
{
[self setFrameForPortraitAndUpsideDownOrientation];
}
}
- (void)willAnimateRotationToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft
|| toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
[self setFrameForLeftAndRightOrientation];
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
{
[self setFrameForPortraitAndUpsideDownOrientation];
}
}
-(void)setFrameForLeftAndRightOrientation
{
if(IS_IPAD)
{
// Write here for left and right orientation
}
else if(is_iPhone)
{
// Write here for iPhone land scape ;
}
-(void)setFrameForPortraitAndUpsideDownOrientation
{
if(IS_IPAD)
{
// Write here for Portrait orientation for iPad
}
else if(is_iPhone)
{
// Write here for iPhone Portrait orientation ;
}
}
See my answer at How to create a landscape-view only ios application for a similar question. All you have to do is to implement one method and your app will be forced to autorotate to the direction you want it.
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
This will force your app to rotate to the UIInterfaceOrientationLandscapeLeft direction by providing your ViewController with only one preferred orientation.

How should I determine how to orient a view in landscape if the UIInterfaceOrientation landscape values are the same constant?

I want to present a view that responds to orientation changes but for various reasons can't use iOS's built-in autorotation. In viewDidLoad I use the current orientation to determine the initial layout of the view:
_originalOrientation = [UIDevice currentDevice].orientation;
// if we were launched flat or unknown, use the status bar orientation as a guide
if (_originalOrientation == UIDeviceOrientationUnknown ||
_originalOrientation == UIDeviceOrientationFaceDown ||
_originalOrientation == UIDeviceOrientationFaceUp) {
_originalOrientation = UIDeviceOrientationFromInterfaceOrientation([UIApplication sharedApplication].statusBarOrientation);
}
As you can see from my comment, I need to handle the case where [UIDevice currentDevice].orientation is not a usable direction (i.e. the device is flat or in an unknown orientation). In this scenario, I attempt to use the statusBarOrientation to infer the device's orientation (using UIViewController's interfaceOrientation would be an alternative way to get the same information):
UIDeviceOrientation UIDeviceOrientationFromInterfaceOrientation(UIInterfaceOrientation interface) {
// note: because UIInterfaceOrientationLandscapeLeft and UIInterfaceOrientationLandscapeRight have the same value, this conversion can't distinguish them
if (interface == UIInterfaceOrientationLandscapeLeft) {
return UIDeviceOrientationLandscapeLeft;
} else if (interface == UIInterfaceOrientationLandscapeRight) {
return UIDeviceOrientationLandscapeRight;
} else if (interface == UIInterfaceOrientationPortraitUpsideDown) {
return UIDeviceOrientationPortraitUpsideDown;
} else {
return UIDeviceOrientationPortrait;
}
}
However my logic can't accurately discern the two landscape cases because they are defined UIApplication.h to be the same constant value:
// Note that UIInterfaceOrientationLandscapeLeft is equal to UIDeviceOrientationLandscapeRight (and vice versa).
// This is because rotating the device to the left requires rotating the content to the right.
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
};
Is there an alternative way I can distinguish between UIInterfaceOrientationLandscapeLeft and UIInterfaceOrientationLandscapeRight? Is there a better way for me to perform my "fallback" logic besides using the status bar orientation?
You wrote:
However my logic can't accurately discern the two landscape cases
because they are defined UIApplication.h to be the same constant value
I am pretty sure that they are not! The values for interface and device orientations are swapped. See UIApplication.h:
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
};
The interface orientation UIInterfaceOrientationLandscapeLeft is equal to the device orientation UIDeviceOrientationLandscapeRight, and vice versa. But:
UIInterfaceOrientationLandscapeLeft != UIInterfaceOrientationLandscapeRight
UIDeviceOrientationLandscapeLeft != UIDeviceOrientationLandscapeRight
Try this code, I assume that will fix the problem:
UIDeviceOrientation UIDeviceOrientationFromInterfaceOrientation(UIInterfaceOrientation interface) {
// interface orientation left is device orientation right
if (interface == UIInterfaceOrientationLandscapeLeft) {
return UIDeviceOrientationLandscapeRight;
// interface orientation right is device orientation left
} else if (interface == UIInterfaceOrientationLandscapeRight) {
return UIDeviceOrientationLandscapeLeft;
} else if (interface == UIInterfaceOrientationPortraitUpsideDown) {
return UIDeviceOrientationPortraitUpsideDown;
} else {
return UIDeviceOrientationPortrait;
}
}
BTW, you should also consider to use an own prefix for your function instead of UI, otherwise it may be easy to mistakenly assume that UIDeviceOrientationFromInterfaceOrientation is an API function.
The orientation property of UIDevice is an enum that does distinguish between landscape left and right (their values are 3 and 4 respectively), so you can check that value.
typedef enum {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait,
UIDeviceOrientationPortraitUpsideDown,
UIDeviceOrientationLandscapeLeft,
UIDeviceOrientationLandscapeRight,
UIDeviceOrientationFaceUp,
UIDeviceOrientationFaceDown
} UIDeviceOrientation;
If you're showing what the camera is seeing, i would ignore all orientations and show the user a preview of what the devices sees in portrait. What they see will always be "correct", and never accidentally upside down.
You always can determine device orientation using gravity property of CMDeviceMotion class. Property return a normalized vector pointed to Earth center (aka real gravity vector). If you not interested in angles, you can test only signs and generate constants for your purpose.
This is how I have done it in the pass
Create a global variable called previousOr. Then in your first viewController use the following code to determine the status bar position. I put it in the viewDidAppear
if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft) {
previousOr = [NSString stringWithFormat:#"L"];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight) {
previousOr = [NSString stringWithFormat:#"L"];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
previousOr = [NSString stringWithFormat:#"P"];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown) {
previousOr = [NSString stringWithFormat:#"P"];
}
Then in your subsequent viewControllers you have the following in the ViewDidLoad methods, this will detect if the device is portrait or landscape or if the device is flat what the device was in before they placed it flat:
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
NSLog(#"landscape");
[self switchToLandscape];
}
else if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)) {
NSLog(#"portrait");
[self switchToPortrait];
}
else {
if ([previousOr isEqualToString:#"L"]) {
[self switchToLandscape];
}
else {
[self switchToPortrait];
}
}
Then you also have the following to do the re-plotting of elements on the view
- (void)switchToLandscape {
previousOr = [NSString stringWithFormat:#"L"];
//do stuff like replot centers
}
- (void)switchToPortrait {
previousOr = [NSString stringWithFormat:#"P"];
//do stuff like replot centers
}
and then you also have the following to detect the change in orientation:
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft) {
[self switchToLandscape];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight) {
[self switchToLandscape];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
[self switchToPortrait];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown) {
[self switchToPortrait];
}
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(BOOL) shouldAutorotate {
return YES;
}
NOTE; I put in both shouldAutorotateToInterfaceOrientation and shouldAutoRotate for backward compatibility.
Had face the same issue. here is the answer, always go for UIIntefaceOrientation to check whether current orientation is Landscape or Portrait.
OBJECTIVE C :
if([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeRight)
{
//Go Here for landscape
}
else if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortraitUpsideDown)
{
//Go Here for Portrait
}
SWIFT :
let currentOrient : UIInterfaceOrientation = UIApplication.shared.statusBarOrientation
if currentOrient == UIInterfaceOrientation.landscapeLeft || currentOrient == UIInterfaceOrientation.landscapeRight
{
//Go Here for landscape
}
else if currentOrient == UIInterfaceOrientation.portrait || currentOrient == UIInterfaceOrientation.portraitUpsideDown
{
//Go Here for Portrait
}

Orientation issue in iPad ios6

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.

Knowing the interface orientation of an iPad at application start

I am trying to figure out my iPad's orientation at start up on a flat table.
I always says it's starting in portrait mode, which it isn't true.
I have used the code sampled here to detect the orientation at start up.
It so happens that when my device is face up on a flat surface it claims it is in portrait mode. However the status bar is visually in landscape mode.
Is there a way around this?
I am using iOS 5 and Xcode 4.3.
EDIT: More details
Here is my update orientation method:
- (void)updateOrientation {
UIInterfaceOrientation iOrientation = self.interfaceOrientation;//[[UIApplication sharedApplication] statusBarOrientation];
UIDeviceOrientation dOrientation = [UIDevice currentDevice].orientation;
bool landscape;
if (dOrientation == UIDeviceOrientationUnknown || dOrientation == UIDeviceOrientationFaceUp || dOrientation == UIDeviceOrientationFaceDown) {
// If the device is laying down, use the UIInterfaceOrientation based on the status bar.
landscape = UIInterfaceOrientationIsLandscape(iOrientation);
} else {
// If the device is not laying down, use UIDeviceOrientation.
landscape = UIDeviceOrientationIsLandscape(dOrientation);
// There's a bug in iOS!!!! http://openradar.appspot.com/7216046
// So values needs to be reversed for landscape!
if (dOrientation == UIDeviceOrientationLandscapeLeft) iOrientation = UIInterfaceOrientationLandscapeRight;
else if (dOrientation == UIDeviceOrientationLandscapeRight) iOrientation = UIInterfaceOrientationLandscapeLeft;
else if (dOrientation == UIDeviceOrientationPortrait) iOrientation = UIInterfaceOrientationPortrait;
else if (dOrientation == UIDeviceOrientationPortraitUpsideDown) iOrientation = UIInterfaceOrientationPortraitUpsideDown;
}
whiteView.hidden = NO;
splashScreen.hidden = NO;
if (landscape) {
splashScreen.image = [UIImage imageNamed:#"Default-Landscape~ipad"];
} else {
splashScreen.image = [UIImage imageNamed:#"Default-Portrait~ipad"];
}
splashScreen.contentMode = UIViewContentModeScaleToFill;
[self.view bringSubviewToFront:whiteView];
[self.view bringSubviewToFront:splashScreen];
// Set the status bar to the right spot just in case
[[UIApplication sharedApplication] setStatusBarOrientation:iOrientation];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (splashScreen){
[self updateOrientation];
[UIView animateWithDuration:0.5 delay:1 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
splashScreen.alpha = 0;
}
completion:^(BOOL success){
[splashScreen removeFromSuperview];
splashScreen = nil;
}];
[UIView animateWithDuration:0.5 delay:1.5 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
whiteView.alpha = 0;
}
completion:^(BOOL success){
[whiteView removeFromSuperview];
whiteView = nil;
}];
}
The problem is noticeable when I start my app in a flat surface in landscape mode I see the wrong image being loaded up for the spashscreen.
Use [[UIApplication sharedApplication] statusBarOrientation] instead of [UIDevice currentDevice] orientation].
There's a difference between device orientation and user interface orientation (and some elaboration can be found on this related question). Many apps might have a user interface designed to only work certain ways even though the device is pointed another way.
I'm experiencing the same problem, and I have not found any good solution.
It seems that [[UIApplication sharedApplication] statusBarOrientation] always return 1 before application:didFinishLaunchingWithOptions: has finish, and only if your device is face up (maybe face down too, i have not tried)
I finally done this :
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// For the cases where device is not face up.
if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
[self doTheJobInPortrait];
else
[self doTheJobInLandscape];
// For the cases where device is face up
[NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:#selector(hackForFaceUpLandscapeDevices) userInfo:nil repeats:NO];
}
-(void)hackForFaceUpLandscapeDevices {
if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
[self doTheJobInPortrait];
else
[self doTheJobInLandscape];
}
Of course, the job will be done two times, and in face up lanscape mode there will be a short moment where your interface will be in portrait...
If someone find a better solution, I would be glad to know it.
That's why there is often used a 'blank view' at startup, that just initializes your app. When the first view is laoded, you can easily check for the correct device-orientation.
After this you load your device-orientation-specific View. So you have:
One ViewController
One Blank View
Two Views with content (one landscape, one portrait)
I think, e. g. Safari Mobile does it that way.

Resources