49

In sample logs posted in this question, the results are identical. Does anyone know if there is meant to be a logical difference between the two?

Even Apple's description is confusing. Here is the description of scale:

The natural scale factor associated with the screen ... This value reflects the scale factor needed to convert from the default logical coordinate space into the device coordinate space of this screen...

Here is their description of nativeScale:

The native scale factor for the physical screen

What is the difference between natural and native?

Community
  • 1
  • 1
Dev Kanchen
  • 2,332
  • 3
  • 28
  • 40

2 Answers2

40

Both scale and nativeScale tell you how many pixels a point corresponds to. But keep in mind that points are rendered to an intermediate buffer of pixels, which is then resized to match the screen resolution. So, when we ask, "1 pt corresponds to how many pixels?" it might mean intermediate pixels (scale) or the final pixels (nativeScale).

On an iPhone 6 Plus (or equivalently sized device), scale is 3, but nativeScale is 2.6. This is because content is rendered at 3x (1 point = 3 pixels) but then the resulting bitmap is scaled down, resulting in 1 point = 2.6 pixels.

So scale deals with the intermediate bitmap, and nativeScale deals with the final bitmap.


This is without display zoom. If you enable display zoom, scale remains the same, at 3, since the intermediate buffer is still rendered at 1 point = 3 pixels. But native scale becomes 2.8.

So, if you want to check the physical screen, use scale. For example, if you have an app that runs only on the iPhone Plus, you could do:

if scale != 3 {
  print("Not supported")
}

Not:

if nativeScale != 2.6 {
  print("Not supported")
}

The second code fragment fails to do what was expected when the user enables display zoom.

Eugene
  • 3,417
  • 5
  • 25
  • 49
Kartick Vaddadi
  • 4,818
  • 6
  • 39
  • 55
  • 2
    There's a nice table with that scales on Apple documentation: https://developer.apple.com/library/content/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html#//apple_ref/doc/uid/TP40013599-CH108-SW2 – Ricardo Barroso May 29 '18 at 17:28
30

The nativeBounds and nativeScale properties are mostly meant for use with OpenGL and represent the actual pixel size and the points-to-pixels scaling factor that you’d use to draw to precisely the screen’s resolution, allowing you to avoid the additional rendering cost of drawing at the virtual 1242×2208 size. For instance, with a CAEAGLLayer, you’d do this:

theGLLayer.contentsScale = [UIScreen mainScreen].nativeScale;

…and then only have to render its content at the size of the nativeBounds, i.e. 1080×1920.

The sample logs in that question are from the simulator, which as always is not guaranteed to behave identically to an actual device.

Noah Witherspoon
  • 57,021
  • 16
  • 130
  • 131
  • That makes sense. Would you have a log handy to confirm? If not I could get around to it some time later. – Dev Kanchen Sep 16 '14 at 15:31
  • Not one that I can share yet, sorry :) – Noah Witherspoon Sep 16 '14 at 15:38
  • 5
    No worries. From the simulator it looks like the scale/nativeScale are being used to indicate whether the app is rendering natively at the 6-Plus resolution or being scaled up from 2x. So for example, if I DON'T include a 2208x1242 launch image, then the app is launched as a 2x app, scaled up to 3x. In this case, the "nativeScale" is being reported as 3x while the "scale" is being reported as 2x. – Dev Kanchen Sep 16 '14 at 17:57
  • Code: NSLog(@"\nNative scale: %1.2f\nScale: %1.2f", [[UIScreen mainScreen] nativeScale], [[UIScreen mainScreen] scale]); Results, @"Native scale: 3.00 \nScale: 2.00" for 2x app scaled to 3x (no launch image), and @"Native scale: 3.00 \nScale: 3.00" for native 3x app (with 6-Plus launch image). – Dev Kanchen Sep 16 '14 at 17:59
  • So "scale" performs that one role already - of communicating if the app is running scaled (from 2x to 3x) or native. For nativeBounds and nativeScale (particularly nativeScale) to additionally correspond to actual screen-pixel values (and not the 3x), "nativeScale" would have to throw some value other than 3.00 (top of my head, 3.00 * 0.87 scaling factor from the 3x resolution to native = 2.61). This would have to be verified once the devices are released. I hope "no logs yet" means we may have an answer after Friday? :) Can be hopeful. – Dev Kanchen Sep 16 '14 at 18:07
  • Yep, that’s the value I would expect to see for `nativeScale` on a real device. – Noah Witherspoon Sep 16 '14 at 18:10
  • 2
    See barfoon's comment on this answer - http://stackoverflow.com/a/25964199/303179. This confirms the expected value of nativeScale on iPhone 6 Plus. Now recapping to my comment on "Sep 16 at 17:57", the last thing left to confirm is the value of nativeScale (3x or 2.61x) on a DEVICE, when the app does NOT include a 2208x1242 launch image (when it behaves as a 2x app, scaled to 3x). @Noah Witherspoon, could you please check this (I won't have a 6-Plus device for the foreseeable future). P.S: Apologies for the delay, I've been without internet for a couple of weeks. – Dev Kanchen Oct 09 '14 at 13:08
  • The nativeScale of iPhone 6 Plus running in scaled mode (ie scaled up iPhone 5 app) is 2.61x something, not 3x. This effectively differentiates iPhoen 6 Plus from iPhone 5, even when the iPhone 6 Plus runs as a iPhone 5. Because scale returns 2 and nativeScale returns 2.61x. – Jonny Jun 30 '15 at 02:11