34

How can I detect whether a user has an iPhone 6 Plus in standard or zoomed mode? Is this possible?

I've tried [UIScreen mainScreen].scale and it reports 3.0 in both cases.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
barfoon
  • 27,481
  • 26
  • 92
  • 138

6 Answers6

17

WORKING SOLUTION:

//Display Zoom mode
var isZoomed: Bool {
    return UIScreen.main.scale < UIScreen.main.nativeScale
}

OLD SOLUTION (not reliable in some edge case):

var isZoomed: Bool { return UIScreen.main.scale != UIScreen.main.nativeScale }

P.S: Please do not confuse these features from the iPhone settings:

  1. Settings -> Display & Brightness -> Display Zoom

with:

  1. Settings -> Accessibility -> Zoom.

Here we check for the first type.

Starsky
  • 1,829
  • 18
  • 25
  • It doesn't work, unfortunately. 12 mini zoomed: scale 3.0, nativeScale 3.515625 ✅ 12 mini no zoom: scale 3.0, nativeScale 3.0 ✅ SE 1st gen zoomed: scale 2.0, nativeScale 2.0 ❌ SE 1st gen no zoom: scale 2.0, nativeScale 1.7066666666666668❌ – Darek Cieśla Mar 08 '21 at 10:54
  • @DarekCieśla that is a nice find. I didn't test absolutely all devices. I think this might be a bug with iPhones SE 1st gen, since all the other devices which I tested on, worked perfectly fine. – Starsky Mar 11 '21 at 15:02
  • 1
    I just tested this on all available simulators in xcode 12 (including SE 2nd Gen) and returned correct results on all. I didn't test it on SE 1st Gen since it doesn't support iOS 14. – Fouad Mar 19 '21 at 16:02
  • 1
    @Fouad SE1 *does* support iOS14 [...]. The comparison above returns false for SE1 because it is the only device that does not support Zoomed Mode, and thus its scale vs nativeScale is always the same. That being said, the code if safe to use on all devices, thanks @Starsky! – Shengchalover May 17 '21 at 08:22
  • No! Simulators return different value with devices! – PowHu May 23 '21 at 02:12
  • This returns true on an iPhone 13 mini with zoom off. There has to be some environment value similar to `sizeCategory` Apple can give us? – GarySabo Feb 17 '22 at 23:20
  • @GarySabo Please check the updated answer. From my tests, it is more reliable, even for iPhose SE 1st Gen which doesn't have Zoom mode. – Starsky Feb 18 '22 at 11:04
14

There's a new member

[[UIScreen mainScreen] nativeScale]

which should do what you want. It's only available on iOS 8, so you'll need to guard it

Paul Franceus
  • 410
  • 2
  • 7
  • 1
    This worked for me! Just had to add mainScreen(). "UIScreen.mainScreen().nativeScale". Very useful to get images from a web service by their width & height and into an image view :D – nmdias Jun 23 '15 at 12:01
13

[UIScreen mainScreen].currentMode reports:

<UIScreenMode: 0x17802f240; size = 1242.000000 x 2208.000000> // STANDARD
<UIScreenMode: 0x178226be0; size = 1125.000000 x 2001.000000> // ZOOMED
Maheswaran Ravisankar
  • 17,652
  • 6
  • 47
  • 69
barfoon
  • 27,481
  • 26
  • 92
  • 138
10

The following code may be used to get bounds, coordinateSpace, nativeScale and scale, i.e. on an iPhone 6 Plus the nativeScale is 2.608 and when the device in run in Zoomed Mode it is 2.88 (note that it is different in the simulator):

UIScreen *mainScreen = [UIScreen mainScreen];
NSLog(@"Screen bounds: %@, Screen resolution: %@, scale: %f, nativeScale: %f",
          NSStringFromCGRect(mainScreen.bounds), mainScreen.coordinateSpace, mainScreen.scale, mainScreen.nativeScale);

Code for detecting iPhone 6 Plus:

-(BOOL)iPhone6PlusDevice{
    // Scale is 3 currently only for iPhone 6 Plus
    if ([UIScreen mainScreen].scale > 2.9) return YES;
    return NO;
}

or

 -(BOOL)iPhone6PlusUnZoomed{
        if ([self iPhone6PlusDevice]){
            if ([UIScreen mainScreen].bounds.size.height > 720.0) return YES;  // Height is 736, but 667 when zoomed.
        }
        return NO;
    }

Note: If you are checking for iPhone 6 Plus, to adjust the user interface then don´t rely on .nativeScale, because the simulator and an actual device give different results.

Sverrisson
  • 17,970
  • 5
  • 66
  • 62
  • 2
    I'm running my extension in the new Messages app which has been properly updated for the new screen sizes in iOS8 (e.g. one that is not 'zoomed'), and `screenScale: 3.000000`, and `nativeScale: 2.608696` – barfoon Sep 22 '14 at 05:56
  • @barfoon what were the screen resolutions reported? As I live in a country without Apple store, I haven´t been able to buy the new iPhone 6 Plus. – Sverrisson Sep 22 '14 at 14:37
  • nativeScale isn't to do with whether or not the app is being run in scaled mode: http://stackoverflow.com/questions/25871858/what-is-the-difference-between-nativescale-and-scale-on-uiscreen-in-ios8 – HHHH Nov 30 '14 at 13:29
  • @HHHH Your right and I have updated the text to reflect that although the code is still valid. – Sverrisson Nov 30 '14 at 15:41
7

Updated macros from Paula Chavarría's answer for iOS 8 (where [UIScreen mainScreen].bounds.size is orientation dependent):

#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_5 (IS_IPHONE && (MAX([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width) == 568.0) && ((IS_OS_8_OR_LATER && [UIScreen mainScreen].nativeScale == [UIScreen mainScreen].scale) || !IS_OS_8_OR_LATER))
#define IS_STANDARD_IPHONE_6 (IS_IPHONE && MAX([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width) == 667.0  && IS_OS_8_OR_LATER && [UIScreen mainScreen].nativeScale == [UIScreen mainScreen].scale)
#define IS_ZOOMED_IPHONE_6 (IS_IPHONE && MAX([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width) == 568.0 && IS_OS_8_OR_LATER && [UIScreen mainScreen].nativeScale > [UIScreen mainScreen].scale)
#define IS_STANDARD_IPHONE_6_PLUS (IS_IPHONE && MAX([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width) == 736.0)
#define IS_ZOOMED_IPHONE_6_PLUS (IS_IPHONE && MAX([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width) == 667.0 && IS_OS_8_OR_LATER && [UIScreen mainScreen].nativeScale < [UIScreen mainScreen].scale)
#define IS_IPHONE_6 (IS_STANDARD_IPHONE_6 || IS_ZOOMED_IPHONE_6)
#define IS_IPHONE_6_PLUS (IS_STANDARD_IPHONE_6_PLUS || IS_ZOOMED_IPHONE_6_PLUS)
Community
  • 1
  • 1
xZenon
  • 655
  • 6
  • 18
5

These option is used to detect iPhone Devices.

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0) 
Vaibhav Sharma
  • 1,123
  • 10
  • 22
  • Since iOS 8 `[UIScreen mainScreen].bounds.size` became orientation dependent and these macros are broken in landscape mode. Could be fixed by using MAX(width, height) for value comparisons. Please see my answer below. – xZenon Aug 24 '15 at 01:10