iOS get physical screen size programmatically? - iphone

Is this possible? I want the number of inches, not the number of pixels. I know it is approximately 160 ppi. But not exactly.

There isn't an API that will give you this. Your best bet is to look at the device's screen size (in points) and from that surmise if it's an iPad or iPhone etc., and then use hard-coded values for the screen sizes.
Here's some code to get the screen size:
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
Be aware that width and height might be swapped, depending on device orientation.

If it were available it would be in UIScreen or UIDevice but it is not there.
You can infer it from info in Erica's UIDevice-extension and the specs for each device listed here on Wikipedia.

Here's a short method that estimates the device screen size. It's updated as to the latest devices, but may fail on future ones (as all methods of guessing might). It will also get confused if the device is being mirrored (returns the device's screen size, not the mirrored screen size)
#define SCREEN_SIZE_IPHONE_CLASSIC 3.5
#define SCREEN_SIZE_IPHONE_TALL 4.0
#define SCREEN_SIZE_IPAD_CLASSIC 9.7
+ (CGFloat)screenPhysicalSize
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
CGSize result = [[UIScreen mainScreen] bounds].size;
if (result.height < 500)
return SCREEN_SIZE_IPHONE_CLASSIC; // iPhone 4S / 4th Gen iPod Touch or earlier
else
return SCREEN_SIZE_IPHONE_TALL; // iPhone 5
}
else
{
return SCREEN_SIZE_IPAD_CLASSIC; // iPad
}
}

You might need use [UIScreen mainScreen].scale;
CGFloat scale = [UIScreen mainScreen].scale;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat physicalWidth = screenRect.size.width * scale;
CGFloat physicalHeight = screenRect.size.height * scale;

Maybe Jeff Hay's code can be adapted to include iPad Mini. The trick is to get the device's model identifier. The most recent non-retina iPad is "iPad2,4" and the first iPad mini is "iPad2,5". Now all you need to check is if the screen scaling is 1.0 (non-retina)
Although this code is not future-proof, you can always add more rules for model identifiers.
#import <sys/utsname.h>
#define SCREEN_SIZE_IPAD_MINI 7.9
struct utsname systemInfo;
uname(&systemInfo);
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && strcasecmp(systemInfo.machine, "iPad2,5") >= 0 [[UIScreen mainScreen] scale] == 1.0)
return SCREEN_SIZE_IPAD_MINI

The "formula" I use is
#define IS_iPhone5 ( fabs( (double)[ [ UIScreen mainScreen ] bounds ].size.height - (double)568 ) < DBL_EPSILON )

Since this question has been asked, I’ve created an open-source library to handle this problem: IRLSize. It can be used in either direction: to measure the size of a view (or the whole screen) in real-world dimensions, or to set the size of a view to a specific real-world dimension.

note: screen rotation matters here
extension UIScreen {
var physicalSize:CGSize {
return CGSize(width: bounds.width*scale, height: bounds.height*scale)
}
}
using:
print(UIScreen.main.physicalSize)

Here is a Swift way to get 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:
https://github.com/goktugyil/EZSwiftExtensions

Nobody said about fixedCoordinateSpace. In Swift 3 to get the screen dimensions in a portrait-up orientation you should use: UIScreen.main.fixedCoordinateSpace.bounds

CGFloat scale = [UIScreen mainScreen].scale;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width * (scale/100.0f);
CGFloat screenHeight = screenRect.size.height * (scale/100.0f);
scale is persent!

Related

Screen size in pixels (iPhone 6)

According to the page here: http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions the iPhone 6 screen size in pixels should be 750×1334 (1334x750 landscape) however my application seems to think the screen dimensions are 667/375 in landscape and it's not being rendered properly to the entire screen. Here's the code I'm using to get the window dimensions when the application launches as well as opengl.
applicationDidFinishLaunching:
CGRect rect = [[UIScreen mainScreen] bounds];
CGFloat screenW = rect.size.width;
CGFloat screenH = rect.size.height;
initGL:
CGRect rect = [glView bounds];
CGFloat screenW = rect.size.width;
CGFloat screenH = rect.size.height;
glOrthof(0, screenW, 0, screenH, -1, 1);
Both functions print out the same values: 667w/375h. Could this have to do with an issue I had with the splash image, where basically I had to rename it from Default-667h#2x.png to Default-375w-667h#2x.png to get it to load properly? I feel like this is something simple I'm missing here, any help is appreciated.
It is is ok. What you see is logical points. These get translated into physical pixels. In case of iPhone 6 it is 2x.

How to distinguish between iPhone and iPhone (Retina 3.5 inch) Programmatically? [duplicate]

This question already has answers here:
Detect Retina Display
(14 answers)
Closed 9 years ago.
Its easy to check whether device is iPhone 5 or iPhone, by checking its height, as given below
if([UIScreen mainScreen].bounds.size.height == 568){
// iPhone 5
} else{
// Regular iPhone
}
However, I want to know, after coming in else body 480 height , I want to check whether its iPhone or iPhone retina?
How can do that?
My main target is to set navigation, as given in my another question
iOS XIB
Thanks
If you really need this, you can use something like this:
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
if ([[UIScreen mainScreen] scale] >= 2.0) {
// retina
}
else {
// not retina
}
}
Define as macro in pch file as below
#define IS_RETINA ([[UIScreen mainScreen] respondsToSelector:#selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))
I guess you have to check whether the screen responds to the scale message and its value is 2.0
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]
&&
[[UIScreen mainScreen] scale] == 2.0)
{
//Retina
}
else
{
//Not Retina
}
Use this method..
Return YES it means its retina otherwise non-retina,
+(BOOL)iPhoneRetina
{
return ([[UIScreen mainScreen] respondsToSelector:#selector(scale)] && [[UIScreen mainScreen] scale] == 2.0) ;
}

Position elements according to screen size in Objective C, ios6, Xcode

I have a UIScrollView which scrolls horizontally from left to right.
I want to be able to vertically position my UIScrollView on the Y axis according to the screen size of the iPhone. E.g iPhone 4 and iPhone 5.
CGFloat startX = (70.0f * ((float)[_attachments count] - 1.0f) + padding);
CGFloat startY = 295;
CGFloat width = 64;
CGFloat height = 64;
Right now I start my Y position at 295 which works okay with the iPhone 4 but not on iPhone 5.
How would I change the startY to accommodate the same position for different screen size?
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568)
{
//iphone5
}
else
{
//iphone4
}
You can set your y value accordingly
Do use layoutSubviews in your view ...
- (void)layoutSubviews {
CGRect frame = self.bounds;
frame.origin.y += frame.size.height - _scrollView.frame.size.height;
if ( ! CGRectEqualToRect( _scrollView.frame, frame ) {
_scrollView.frame = frame;
}
}
... I assume that your horizontal scroll view is in _scrollView ivar and also that the _scrollView.frame.size.height contains correct height of your _scrollView. If not, replace _scrollView.frame.size.height with some constant which does contain your UIScrollView height.
Why the condition with CGRectEqualToRect? Because layoutSubviews can be called very often and when you set new frame (even if it equals) to it, UIScrollView can stop scrolling.
you can do it like this-
first get the width and the height of the screen
CGRect screenBounds = [UIScreen mainScreen].bounds ;
CGFloat width = CGRectGetWidth(screenBounds);
CGFloat height = CGRectGetHeight(screenBounds) ;
now create a method which will do some calculations and return an int
-(NSInteger) getwidth:-(NSInteger *) value
{
int temp = (value * 100) / 480;
return int((height * temp) / 100);
}
-(NSInteger) getheight:-(NSInteger *) value
{
var temp = (value * 100) / 320;
return int((width * temp) / 100);
}
now set the bounds of view according to these function
actind.frame=CGRectMake(getWidth(20),getheight(20),16,16);
this will work on all the devices and the views will arrange themselves according to the width and height of the screen.
hope this will help for you. :)

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.
}
}

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