EXC_BAD_ACCESS when trying to get iPhone screen dimensions - iphone

I'm trying to make certain elements resize according to the screen dimensions when the interface orientation changes. I've read in various places (including a few answers on here) that the way to get the bounds of the screen is to use [[UIScreen] mainScreen] bounds]. So I've added this code to see how it behaves:
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
NSLog(#"view dimensions: (%#, %#)", [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
}
But when running it, as soon as I rotate the screen I get an EXC_BAD_ACCESS message. Is there something about the scope of the willRotateToInterfaceOrientation function that doesn't allow me to call for the screen bounds? If so, how would I go about it?

%# format specifier expects format parameter to be objective-c object, while what you provide is plain float. To print float numbers use %f specifier:
NSLog(#"view dimensions: (%f, %f)", [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);

Related

UIScreen mirroredScreen property always returns nil

I want to present unique content on the external connected display if mirroring is not supported by the device (original iPad) but want to use screen mirroring if it's iPad 2. Now when I try to code this as follows:
if ([UIScreen instancesRespondToSelector:#selector(mirroredScreen)] && [[UIScreen mainScreen] mirroredScreen] == nil) {
// Mirroring not supported. Present unique content on external display
}
[[UIScreen mainScreen] mirroredScreen] always returns nil.
Am I doing something wrong?
As I understand the documentation, mirroredScreen will reference the main screen if you access the property on a secondary screen that actually is the mirrored screen. As in:
if ([[UIScreen screens] count] > 1) {
UIScreen *secondaryScreen = [[UIScreen screens] objectAtIndex:1];
NSLog(#"%#", secondaryScreen.mirroredScreen); // will reference the mainScreen
}
[[UIScreen mainScreen] mirroredScreen] would then always return nil because the mainScreen does not mirror itself.
Apple have a recommendation about the way to detect if the screen is mirrored or not here : http://developer.apple.com/library/ios/#qa/qa1738/_index.html
UIScreen *aScreen;
NSArray *screens = [UIScreen screens];
for (aScreen in screens)
{
if ([aScreen respondsToSelector:#selector(mirroredScreen)]
&& [aScreen mirroredScreen] == [UIScreen mainScreen])
{
// The main screen is being mirrored.
}
else
{
// The main screen is not being mirrored, or
// you are not running on a compatible device.
}
}

Defining constant for screen width

I have a constant defined with screen width to 320. This is being used at multiple places in my code. I have to change this to take value from current device and I do not want to touch all these places. So, I want to define a constant for this with value:
[[UIScreen mainScreen] bounds].size.width
#define kScreenWidth [[UIScreen mainScreen] bounds].size.width
But it is giving me lot of compilation errors. Any clue?
[[UIScreen mainScreen] applicationFrame].size.width

why would [[UIScreen mainScreen] scale] return 0?

I thought I was doing something relatively simple, but I guess not.
Running:
NSLog(#"%f",[[UIScreen mainScreen] scale];
returns 0.000000
The problem is that I am trying to check for a retina display and the:
if([UIScreen respondsToSelector:#selector(scale)] &&
[[UIScreen mainScreen] scale] == 2.0) {
// does not get called on an iPhone 4
}
Doesnt get called. I have tried this both in the simulator as well as on the device.
I guess the answer is How to call [[UIScreen mainScreen] scale] in a universal app for the iphone and ipad

IPhone/IPad: How to get screen width programmatically?

Hi I'm wondering if there's a way to get the width programmatically.
I'm looking for something general enough to accomodate iphone 3gs, iphone 4, ipad. Also, the width should change based on if the device is portrait or landscape (for ipad).
Anybody know how to do this?? I've been looking for a while... thanks!
Take a look at UIScreen.
eg.
CGFloat width = [UIScreen mainScreen].bounds.size.width;
Take a look at the applicationFrame property if you don't want the status bar included (won't affect the width).
UPDATE: It turns out UIScreen (-bounds or -applicationFrame) doesn't take into account the current interface orientation. A more correct approach would be to ask your UIView for its bounds -- assuming this UIView has been auto-rotated by it's View controller.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
CGFloat width = CGRectGetWidth(self.view.bounds);
}
If the view is not being auto-rotated by the View Controller then you will need to check the interface orientation to determine which part of the view bounds represents the 'width' and the 'height'. Note that the frame property will give you the rect of the view in the UIWindow's coordinate space which (by default) won't be taking the interface orientation into account.
CGRect screen = [[UIScreen mainScreen] bounds];
CGFloat width = CGRectGetWidth(screen);
//Bonus height.
CGFloat height = CGRectGetHeight(screen);
This can be done in in 3 lines of code:
// grab the window frame and adjust it for orientation
UIView *rootView = [[[UIApplication sharedApplication] keyWindow]
rootViewController].view;
CGRect originalFrame = [[UIScreen mainScreen] bounds];
CGRect adjustedFrame = [rootView convertRect:originalFrame fromView:nil];
use:
NSLog(#"%f",[[UIScreen mainScreen] bounds].size.width) ;
As of iOS 9.0 there's no way to get the orientation reliably. This is the code I used for an app I design for only portrait mode, so if the app is opened in landscape mode it will still be accurate:
screenHeight = [[UIScreen mainScreen] bounds].size.height;
screenWidth = [[UIScreen mainScreen] bounds].size.width;
if (screenWidth > screenHeight) {
float tempHeight = screenWidth;
screenWidth = screenHeight;
screenHeight = tempHeight;
}
Use this code it will help
[[UIScreen mainScreen] bounds].size.height
[[UIScreen mainScreen] bounds].size.width
Here is a Swift way to get screen sizes, this also takes current interface orientation into account:
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:
https://github.com/goktugyil/EZSwiftExtensions

How can i simplify UIScreen width?

how can i simplify that code in one line?
CGRect screen = [[UIScreen mainScreen] bounds];
NSLog(#"%#", screen.size.width);
Thanks for your time.
This statement will cause an exception, or should:
NSLog(#"%#", screen.size.width);
The width property returns a CGFloat. You would need to change your log statement to:
NSLog(#"%f", screen.size.width);
If you want everything on one line:
NSLog(#"%f", [[[[UIScreen mainScreen] bounds] size] width]);
I would suggest:
NSLog(#"%1.0f", [UIScreen mainScreen].bounds.size.width);
To get both height and width you can use NSStringFromCGSize:
NSLog(#"%#", NSStringFromCGSize([UIScreen mainScreen].bounds.size));