Device orientation at launch - cocoa-touch

I've read ALL of the posts on this topic, but still can't figure this one out.
I add a VC to the window in applicationDidFinishLaunching. The VC contains a UIImageView.
I want to set the image of the UIImageView based on the device orientation, but statusBarOrientation, deviceOrientation, interfaceOrientation, everything I check returns portrait.
There's gotta be something simple I'm missing.
Your help is appreciated.

Have you enabled the other orientations in your Info.plist? There's a graphical editor for this in Xcode 4's project editor.

Sometimes (not sure if this is in every case, or just the simulator), the app will launch in one orientation and then immediately rotate to another orientation to match the device orientation.
I would suggest implementing -[UIViewController willRotateToInterfaceOrientation:duration:] to set your image, which should be called immediately after.

Well.. it seems there were several issues. 1) The simulator doesn't consistently generate orientation (or change in orientation) data as expected. Also, 2) immediately at start up, the device may (or may not) send statusBarOrientation info in time to read that. So, I did this right in the didFinishLaunching method in the app delegate.
// add the splash IV to the window per the current orientation, then animate it away
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait){
self.theSplashIV.image = [UIImage imageNamed:#"Default-Portrait~ipad.png"];
self.theSplashIV.frame = CGRectMake(0, 20, 768, 1004);
}
else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown){
self.theSplashIV.image = [UIImage imageNamed:#"Default-Portrait~ipad.png"];
self.theSplashIV.transform = CGAffineTransformMakeRotation(M_PI);
self.theSplashIV.frame = CGRectMake(0, 0, 768, 1004);
}
else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft){
self.theSplashIV.image = [UIImage imageNamed:#"Default-Landscape~ipad.png"];
self.theSplashIV.transform = CGAffineTransformMakeRotation(M_PI / 2);
self.theSplashIV.frame = CGRectMake(0, 0, 748, 1024);
}
else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight){
self.theSplashIV.image = [UIImage imageNamed:#"Default-Landscape~ipad.png"];
self.theSplashIV.transform = CGAffineTransformMakeRotation(M_PI / -2);
self.theSplashIV.frame = CGRectMake(20, 0, 748, 1024);
}
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
And then I animate away the splash IV with a delay.
Not very elegant, but it works.

Related

change a buttons frame size when another button tapped Xcode

I have an app that I want a button's frame size to change on different devices when another button is tapped. When I tap the button on the iPad the other button's frame size changes and changes back when another button is tapped. However this does not happen when on an iPhone.
this is the original size on the iphone
(568 height)
button.frame = CGRectMake(18,456,126,13);
other height
button.frame = CGRectMake(18,370,126,13);
and this is the size on the iPad
button.frame = CGRectMake(47,577,251,26);
this is the code to change the size of the button when the other button is tapped
-(IBAction)changeSize:(id)sender{
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
int height = [UIScreen mainScreen].bounds.size.height;
if (height == 568) {
self.button.frame = CGRectMake(18,339,100,13);
}
else {
self.button.frame = CGRectMake(18,279,100,13);
}
}
else if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad){
self.button.frame = CGRectMake(47,603,200,26);
}
Like I said it works fine changing the button size on the iPad but not on the iPhone.
Any suggestions?
Thanks
So I had auto layout enable for the iPhone and not for the iPad. Once I disabled it on the iPhone it worked perfectly.

iOS 6 & iOS 7 Status Bar

There are multiple questions about "switching from iOS 6 Status Bar to iOS 7", but I would like to ask the opposite.
My question is: How can I make iOS 6 screen frame slip under the status bar? I tried to move the self.window.frame and self.window.bounds in App Delegate, it is okay to shift up under the status bar, but the bottom will leave a 20 ~ 40px black line.
Here is the codes:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6 && [[[UIDevice currentDevice] systemVersion] floatValue] < 7) {
[application setStatusBarStyle:UIStatusBarStyleLightContent];
self.window.clipsToBounds = YES;
self.window.frame = CGRectMake(0, -20, self.window.frame.size.width, self.window.frame.size.height + 40);
self.window.bounds = CGRectMake(0, -40, self.window.frame.size.width, self.window.frame.size.height + 80);
}
I tried many values, but none fits my needs. What did I miss? I think I'm close.
Here is the mock screenshot I want to achieve ( I know the signal status of iOS 6 is not like this. Just to show the idea )
Note: only needs to support iOS 6+
My final solution is to remove the codes in App Delegate, and add IBOutlet to the header image of each page.
Then, in the method - (void)viewDidLayoutSubviews:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7")) {
[iv_header setFrame:CGRectMake(0, 0, 320, 60)];
}
where the if-case is defined as:
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

ios 7 status bar and navigation bar issue

My app's view is overlapped with status bar and navigationBar in ios7 device so I tried lots of solutions
uncheck 'under top bars' property in storyboard
self.edgesForExtendedLayout = UIRectEdgeNone;
set delta y to -20 in storyboard...
but none of these worked.
My last trial was adding these lines to appdelegate's didFinishLaunchingWithOptions
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
application.statusBarStyle = UIStatusBarStyleLightContent;
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.window.clipsToBounds =YES;
} else {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
}
It works quite well when navigation bar is hidden but when nagivigation is not hidden,
navigationbar's frame is (0, 20, 320, 44) not (0, 0, 320, 44)
So navigationBar's height seems to be 64..
why is this? Hope someone explains me!
Thanks is advance :)
For a better explanation of the differences please see this transition guide (link).
Make sure you set this in viewWillAppear:
self.navigationController.navigationBar.translucent = NO;
self.edgesForExtendedLayout = UIRectEdgeNone;
To avoid the overlapping with the UINavigationBar, you must set its translucent property to NO.
As for the status bar, you have to manually set it by specifying its style and then reposition the whole window's frame. I would add on top of that an iOS 7 condition to make sure that only happen with users running iOS 7.
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
[application setStatusBarStyle:UIStatusBarStyleLightContent];
self.window.clipsToBounds =YES;
self.window.frame = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height - 20);
}

iPhone 5 Auto Layout not Correct

The new iPhone screen has screwed up my app. On the iPhone 3.5 inch screen, everything is out of place. I have two different views in the same storyboard I have tried out detecting and trying to switch storyboard views but nothing has worked yet. Could I get some code on how to switch to the right view at the launch? Do I place this code in my main view controller, or do I put this in my app delegate?
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
// code for 4-inch screen
} else {
// code for 3.5-inch screen
}
What my views look like http://www.fileden.com/files/2012/6/18/3317719/screenshot7.jpg
Initialize this in the app delegate for the app in "didFinishLaunchingWithOptions:" and then call the right NIB or Storyboard for the device/screen size. Create a different Storyboard for each and if you wish use auto layout for iOS 6 in your Storyboard. Start your if Statement with something like this:
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height == 568.0){
//iPhone 5 storyboard
}
else {
// other storyboard here
}

iPhone SDK: Orientation (Landscape and Portrait views)

Okay, I've got my normal app which is in portrait mode. I can force my app to go to landscape mode for a view (using navigationcontroller and viewcontroller) like this:
- (void)viewWillAppear:(BOOL)animated {
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
}
But then when I go back to the main menu (tableview) it goes straight back to portrait. I try this code:
- (void)viewWillAppear:(BOOL)animated {
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
}
But that doesn't work..
Any ideas?
Take a look at the function shouldAutorotateToInterfaceOrientation: in the UIViewController class. This function returns YES if the orientations are supported by your UIView. If you return YES only to the landscape orientation, the iPhone will automatically be put in that orientation.
The following code should do it. Put it in the UIViewController that controls the view that you want to put in landscape mode.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscape);
}
To get this to work, I added this to the rootviewcontroller:
- (void)viewWillAppear:(BOOL)animated {
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
}
This seems to be working now.
Here's what I'm doing to do this:
first, put this define at the top of your file, right under your #imports:
#define degreesToRadian(x) (M_PI * (x) / 180.0)
then, in the viewWillAppear: method
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
if (self.interfaceOrientation == UIInterfaceOrientationPortrait) {
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
self.view.bounds = CGRectMake(0.0, 0.0, 480, 320);
}
if you want that to be animated, then you can wrap the whole thing in an animation block, like so:
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
if (self.interfaceOrientation == UIInterfaceOrientationPortrait) {
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
self.view.bounds = CGRectMake(0.0, 0.0, 480, 320);
}
[UIView commitAnimations];
Then, in your portrait mode controller, you can do the reverse - check to see if its currently in landscape, and if so, rotate it back to Portrait.
You need to edit your Info.plist file to add the UIInterfaceOrientation key with the appropriate value (UIInterfaceOrientationLandscapeRight or UIInterfaceOrientationLandscapeLeft).
You can't use this private API.
There is a solution to do that : it's to use a view controller and adding its view to the window. then in that controller you force landscape in the shouldAutorotate... methode. It works fine, but be sure it's necessary for your project to use that, because it's not very smart  to force the user to turn his iPhone. By the way, here is an example code if you need it.
http://www.geckogeek.fr/iphone-forcer-le-mode-landscape-ou-portrait-en-cours-dexecution.html