iOS project works on iPhone but not in simulator - ios

Bonjour,
My iOS project support landscape and run perfectly on my iPhone 4s 7.1.2 but not in the simulator.
Here some screenshot :
iPhone Landscape
Simulator Landscape
Both screenshots have been taken in landscape mode and the simulator does not seem to resize the board correctly
Here the code I use to change orientation.
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight){
[UIView animateWithDuration:duration animations:^{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
int width = [[UIScreen mainScreen] bounds].size.width - [[UIApplication sharedApplication] statusBarFrame].size.width - 10;
int height = width;
int x = 5;
int y = ([[UIScreen mainScreen] bounds].size.width / 2) - (width / 2);
[board setFrame:CGRectMake(x, y, width, height)];
}];
}
else {
[UIView animateWithDuration:duration animations:^{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
[board setFrame:CGRectMake(0, [UIApplication sharedApplication].statusBarFrame.size.height, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.width)];
}];
}
}
Thanks for your help :)

I haven't tried your code but I strongly believe what you see is caused by the deprecated API. Official documentation here gives details, and the new API that does what you want is viewWillTransitionToSize:withTransitionCoordinator:
Also there are some other questions on stackoverflow like this talking about solutions: willAnimateRotationToInterfaceOrientation not called on ios6/7

Related

UIScreen mainScreen bounds give wrong size

Hi i am initiate a rootViewController programatically (portal only no landscape]
this is the code use
CGRect appFrame = [[UIScreen mainScreen] bounds];
But it does not give correct size. (cut down at bottom screen)
Only this code give correct
CGRect appFrame = [UIScreen mainScreen].applicationFrame
But this code will give warning of depreciated (applicationFrame is depreciated)
(My simulator is IOS 9.3)
How to fix the problem? any help is much appreciate! thanks!
here is screenshoot when using [UIscreen mainscreen].bounds
and here is [UIscreen mainscreen].applicationFrame
[[UIScreen mainScreen] bounds] gives the correct size of the entire window, but it includes the size of the status bar. If you want the size of the status bar ( you can subtract its height), you should use [[UIApplication sharedApplication] statusBarFrame] to get the frame of the status bar. Navigation bars and tab bars generally have a height of 44. So, use CGRectMake() if you need a rectangle for your view:
CGRect frame_screen = [[UIScreen mainScreen] bounds];
CGRect frame_view = CGRectMake(0,0,frame_screen.size.width,frame_screen.size.height - [[UIApplication sharedApplication] statusBarFrame].size.height);
Notice that the last argument of CGRectMake is the height, usually you can minus 44 for a tab bar or navigation bar.
EDIT: Try to log [UIScreen mainScreen].applicationFrame and [[UIScreen mainScreen] bounds] to console and see what the difference is between them. Something like
CGRect frame_screen = [[UIScreen mainScreen] bounds];
NSLog(#"x: %f, y: %f, width: %f, height: %f",frame_screen.origin.x,frame_screen.origin.y,frame_screen.size.width,frame_screen.size.height);
CGRect frame_application = [UIScreen mainScreen].applicationFrame
NSLog(#"x: %f, y: %f, width: %f, height: %f",frame_application.origin.x,frame_application.origin.y,frame_application.size.width,frame_application.size.height);
Then use that information to make [[UIScreen mainScreen] bounds frame how you need it.
you can do the following.
CGRect rect = [UIScreen mainScreen].bounds;
CGRect screenFrame = CGRectMake(0, [[UIApplication sharedApplication] statusBarFrame].size.height, rect.size.width, rect.size.height - [[UIApplication sharedApplication] statusBarFrame].size.height);
Now you can use this screenFrame, I hope this will resolve your problem.
Make sure you have added all resolution splash image on yous's application Images.xcassets
`
Please take a look on Screen shot i attached
`
CGRect appFrame = [[UIScreen mainScreen] bounds]; //This is the
correct way to get your screen size

IOS Landscape Mode not working OPEN GL

Ok tried almost everything and it didn't work.
I need my engine to start up in LandscapeRight mode, therefore i call:
//
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
The problem is that the rest is not rotated at all,
I managed to rotate the view by using:
[pExternViewController setTransform:CGAffineTransformMakeRotation(M_PI/2.0f)];
But it doesn't work as expected, the Frame Buffer size is correct now:
FrameBuffer: width: 960, height: 640
Still you can see it is not 960x640, and i can't figure out why?
Ok, finally made it.
First add this key to your plist file (required)
<key>UILaunchStoryboardName</key>
<string>Launch Screen</string>
Screen Size definitions
#define SCREEN_WIDTH (IOS_VERSION_LOWER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height) : [[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT (IOS_VERSION_LOWER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width) : [[UIScreen mainScreen] bounds].size.height)
#define IOS_VERSION_LOWER_THAN_8 (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
The window initialization
- (void) applicationDidFinishLaunching: (UIApplication*) application
{
// Start in Landscape
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
// Disable Auto Lock screen
[[UIApplication sharedApplication] setIdleTimerDisabled: YES];
// Set Bounds with the proper screen resolution
CGRect screenBounds = [[UIScreen mainScreen] bounds];
screenBounds = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Create window and view controler
m_window = [[UIWindow alloc] initWithFrame: screenBounds];
m_window.backgroundColor = [UIColor redColor];
// Create new view controller
pExternViewController = [SvgzViewController alloc] ;
// Initialize view controler with all pointers set up
if( [pExternViewController initWithFrame: screenBounds ] == nil)
{
assert(!"Failed to initialize screen");
exit(0);
}
// Rotate the window
[m_window setTransform:CGAffineTransformMakeRotation(M_PI/2.0f)];
// Set the proper window center after transformation
m_window.center = CGPointMake(screenBounds.size.height/2, screenBounds.size.width/2);
// Add GL window
[m_window addSubview: pExternViewController];
//
[m_window makeKeyAndVisible];
}
At least no GL side change has to be done by doing it this way.

iOS 7 rotated device not detecting landscape screen bounds

Was trying to change several labels and images width depend on the screen bounds after device gets rotated. Here's what I've tried:
- (void)viewDidLayoutSubviews{
if( UIInterfaceOrientationIsLandscape( [[UIDevice currentDevice] orientation] )) {
CGSize newSize;
newSize = CGSizeMake([[UIScreen mainScreen] bounds].size.width,[[UIScreen mainScreen] bounds].size.height);
NSLog(#"%#",NSStringFromCGSize(newSize));
}else if (UIInterfaceOrientationIsPortrait( [[UIDevice currentDevice] orientation] )){
CGSize newSize;
newSize = CGSizeMake([[UIScreen mainScreen] bounds].size.width,[[UIScreen mainScreen] bounds].size.height);
NSLog(#"%#",NSStringFromCGSize(newSize));
}
}
It's supposed to log different width and height when I change the orientation
(like on iphone5 : {480,320} & {320,480})
works fine on ios8,
but I got the same size results testing both on ios7 simulator and ios7 device.
Any idea would be appreciated.
Only from iOS8
[UIScreen mainScreen].bounds
is interface-oriented (look at session "View Controller Advancements in iOS 8" of WWDC 2014), this means that in landscape mode on iOS8 height and width are reversed.
You can create an helper method like below to have the same behavior:
+(CGRect)getScreenBounds
{
CGRect bounds = [UIScreen mainScreen].bounds;
if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}
return bounds;
}

iAd banner position is wrong on iPhone 6/6 Plus

I'm trying to optimize my SpriteKit App for iPhone 6 and iPhone 6 Plus but the iAd banner position is wrong and I can't change it. It works great on 4" or 3.5" iPhones but on iPhone 6 and 6 Plus the banner isn't at the bottom, it is a bit above it.
Also, I've been searching for this problem in google. There were many solutions but none of them worked for me.
I'm using following code for the iAd banner in my ViewController.m file:
//iAd
#pragma mark iAd Delegate Methods
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
CGRect screen = [[UIScreen mainScreen] bounds];
CGFloat height = CGRectGetHeight(screen);
banner.frame = CGRectOffset(banner.frame, 0, height-banner.frame.size.height);
//Changing the Y-position doesn't change the banner's position
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
if([[NSUserDefaults standardUserDefaults] boolForKey:#"Ads_savedata"] == NO)
[banner setAlpha:0];
else
[banner setAlpha:1];
[banner updateConstraints];
[UIView commitAnimations];
}
- (void) bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[banner setAlpha:0];
[UIView commitAnimations];
}
For me, it looks like the following line doesn't affect the banner's position.
banner.frame = CGRectOffset(banner.frame, 0, height-banner.frame.size.height);
I hope someone can help me with that problem. Thanks for your attention.
I guess its screen width and height problem. Try this once
float SW;
float SH;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (( [[[UIDevice currentDevice] systemVersion] floatValue]<8) && UIInterfaceOrientationIsLandscape(orientation))
{
SW = [[UIScreen mainScreen] bounds].size.height;
SH = [[UIScreen mainScreen] bounds].size.width;
}
else
{
SW = [[UIScreen mainScreen] bounds].size.width;
SH = [[UIScreen mainScreen] bounds].size.height;
}

How to get orientation-dependent height and width of the screen?

I'm trying to programmatically determine the current height and width of my application. I use this:
CGRect screenRect = [[UIScreen mainScreen] bounds];
But this yields a width of 320 and a height of 480, regardless of whether the device is in portrait or landscape orientation. How can I determine the current width and height (i.e. dependent upon the device orientation) of my main screen?
You can use something like UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) to determine the orientation and then use the dimensions accordingly.
HOWEVER, during an orientation change like in UIViewController's
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
Use the orientation passed in toInterfaceOrientation since the UIApplication's statusBarOrientation will still point to the old orientation as it has not yet changed (since you're inside a will event handler).
Summary
There are several related posts to this, but each of them seem to indicate that you have to:
Look at [[UIScreen mainScreen] bounds] to get the dimensions,
Check what orientation you are in, and
Account for the status bar height (if shown)
Links
Iphone: Get current view dimensions or screen dimensions
IPhone/IPad: How to get screen width programmatically?
Objective C - how to get current screen resolution?
“Incorrect” frame / window size after re-orientation in iPhone or iPad
iPhone Dev SDK - get screen width
Working Code
I usually don't go this far, but you piqued my interest. The following code should do the trick. I wrote a Category on UIApplication. I added class methods for getting the currentSize or the size in a given orientation, which is what you would call in UIViewController's willRotateToInterfaceOrientation:duration:.
#interface UIApplication (AppDimensions)
+(CGSize) currentSize;
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation;
#end
#implementation UIApplication (AppDimensions)
+(CGSize) currentSize
{
return [UIApplication sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
CGSize size = [UIScreen mainScreen].bounds.size;
UIApplication *application = [UIApplication sharedApplication];
if (UIInterfaceOrientationIsLandscape(orientation))
{
size = CGSizeMake(size.height, size.width);
}
if (application.statusBarHidden == NO)
{
size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
}
return size;
}
#end
To use the code simple call [UIApplication currentSize]. Also, I ran the above code, so I know it works and reports back the correct responses in all orientations. Note that I factor in the status bar. Interestingly I had to subtract the MIN of the status bar's height and width.
Other thoughts
You could go about getting the dimensions by looking at the UIWindow's rootViewController property. I've looked at this in the past and it similarly reports the same dimensions in both portrait and landscape except it reports having a rotate transform:
(gdb) po [[[[UIApplication sharedApplication] keyWindow]
rootViewController] view]
<UILayoutContainerView: 0xf7296f0; frame =
(0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H;
layer = <CALayer: 0xf729b80>>
(gdb) po [[[[UIApplication
sharedApplication] keyWindow] rootViewController] view]
<UILayoutContainerView: 0xf7296f0; frame = (0 0; 320 480); autoresize
= W+H; layer = <CALayer: 0xf729b80>>
Not sure how your app works, but if you aren't using a navigation controller of some kind, you could have a UIView under your main view with the max height / width of parent and grows / shrinks with parent. Then you could do: [[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame]. That looks pretty intense on one line, but you get the idea.
However, it would still be better to do the above 3 steps under the summary. Start messing with UIWindows and you'll find out weird stuff, like showing a UIAlertView will change UIApplication's keywindow to point at a new UIWindow that the UIAlertView created. Who knew? I did after finding a bug relying on keyWindow and discovering that it changed like that!
This is my solution code !This method can add to NSObject class's Categroy , or you can define a Top custom UIViewController class , and let all of your other UIViewControllers to inherit it .
-(CGRect)currentScreenBoundsDependOnOrientation
{
CGRect screenBounds = [UIScreen mainScreen].bounds ;
CGFloat width = CGRectGetWidth(screenBounds) ;
CGFloat height = CGRectGetHeight(screenBounds) ;
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
screenBounds.size = CGSizeMake(width, height);
}else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
screenBounds.size = CGSizeMake(height, width);
}
return screenBounds ;
}
Note, after IOS8 , as Apple Document of UIScreen's bounds property says :
Discussion
This rectangle is specified in the current coordinate space, which takes into account any interface rotations in effect for the device. Therefore, the value of this property may change when the device rotates between portrait and landscape orientations.
so for the consideration of compatibility , we should detect the IOS version and make the change as below:
#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
-(CGRect)currentScreenBoundsDependOnOrientation
{
CGRect screenBounds = [UIScreen mainScreen].bounds ;
if(IsIOS8){
return screenBounds ;
}
CGFloat width = CGRectGetWidth(screenBounds) ;
CGFloat height = CGRectGetHeight(screenBounds) ;
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
screenBounds.size = CGSizeMake(width, height);
}else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
screenBounds.size = CGSizeMake(height, width);
}
return screenBounds ;
}
Here's a handy macro:
#define SCREEN_WIDTH (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)
#define SCREEN_HEIGHT (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)
In iOS 8+ you should use the viewWillTransitionToSize:withTransitionCoordinator method:
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
// You can store size in an instance variable for later
currentSize = size;
// This is basically an animation block
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Get the new orientation if you want
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
// Adjust your views
[self.myView setFrame:CGRectMake(0, 0, size.width, size.height)];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Anything else you need to do at the end
}];
}
This replaces the deprecated animation method that gave no information about size:
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
As of iOS 8 screen bounds are now returned correct for current orientation. This means an iPad in landscape orientation [UIScreen mainScreen].bounds would return 768 on iOS <=7 and 1024 on iOS 8.
The following returns the correct height and width on all versions released.
-(CGRect)currentScreenBoundsDependOnOrientation
{
NSString *reqSysVer = #"8.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
return [UIScreen mainScreen].bounds;
CGRect screenBounds = [UIScreen mainScreen].bounds ;
CGFloat width = CGRectGetWidth(screenBounds) ;
CGFloat height = CGRectGetHeight(screenBounds) ;
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
screenBounds.size = CGSizeMake(width, height);
NSLog(#"Portrait Height: %f", screenBounds.size.height);
}else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
screenBounds.size = CGSizeMake(height, width);
NSLog(#"Landscape Height: %f", screenBounds.size.height);
}
return screenBounds ;
}
if you want the orientation dependent size and you have a view, you can just use:
view.bounds.size
I wrote category for UIScreen, that works on all iOS versions, so you can use it like this:
[[UIScreen mainScreen] currentScreenSize].
#implementation UIScreen (ScreenSize)
- (CGSize)currentScreenSize {
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBounds.size;
if ( NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1 ) {
UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if ( UIInterfaceOrientationIsLandscape(interfaceOrientation) ) {
screenSize = CGSizeMake(screenSize.height, screenSize.width);
}
}
return screenSize;
}
#end
Here is a Swift way to get orientation dependent screen sizes:
var screenWidth: CGFloat {
if UIInterfaceOrientationIsPortrait(screenOrientation) {
return UIScreen.mainScreen().bounds.size.width
} else {
return UIScreen.mainScreen().bounds.size.height
}
}
var screenHeight: CGFloat {
if UIInterfaceOrientationIsPortrait(screenOrientation) {
return UIScreen.mainScreen().bounds.size.height
} else {
return UIScreen.mainScreen().bounds.size.width
}
}
var screenOrientation: UIInterfaceOrientation {
return UIApplication.sharedApplication().statusBarOrientation
}
These are included as a standard function in a project of mine:
https://github.com/goktugyil/EZSwiftExtensions
float msWidth = [[UIScreen mainScreen] bounds].size.width*(IS_RETINA?2.0f:1.0f);
float msHeight = [[UIScreen mainScreen] bounds].size.height*(IS_RETINA?2.0f:1.0f);
if ( UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ) {
os->setWidth(MIN(msWidth, msHeight));
os->setHeight(MAX(msWidth, msHeight));
} else {
os->setWidth(MAX(msWidth, msHeight));
os->setHeight(MIN(msWidth, msHeight));
}
NSLog(#"screen_w %f", os->getWidth());
NSLog(#"screen_h %f", os->getHeight());
However, on iOS 8.0.2:
+ (NSUInteger)currentWindowWidth
{
NSInteger width = 0;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
CGSize size = [UIScreen mainScreen].bounds.size;
// if (UIInterfaceOrientationIsLandscape(orientation)) {
// width = size.height;
// } else {
width = size.width;
// }
return width;
}
use -> setNeedsDisplay() for the view you want to resize.
Some improvements on the answers offered here, in Swift:
let interfaceOrientation = UIApplication.shared.statusBarOrientation // (< iOS 13)
let screenSize = UIScreen.main.bounds.size
let screenWidth = interfaceOrientation.isPortrait ? screenSize.width : screenSize.height
let screenHeight = interfaceOrientation.isPortrait ? screenSize.height : screenSize.width

Resources