ios: stop falling back to the main screen for pixel conversion

UIScreen.mainScreen is deprecated and ambiguous on a device with two
displays, and Apple's resizability audit flags it. Use the scene's
screen when the view is in a window, since its native scale still
differs from the trait scale on downsampled displays, and the view's own
display scale trait otherwise.

Assisted-by: Claude:claude-fable-5-1
This commit is contained in:
osy
2026-09-24 20:52:49 -05:00
parent 55a89821b6
commit 0ef08849a6
@@ -73,15 +73,25 @@ NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END
#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
/// The native scale of the screen the view is on, which can differ from the trait's scale on downsampled displays.
///
/// A device can have more than one screen so the view's own traits are used until it is in a window.
static inline CGFloat CGViewNativeScale(UIView * _Nonnull view) {
UIScreen *screen = view.window.windowScene.screen;
if (screen) {
return screen.nativeScale;
} else {
return view.traitCollection.displayScale;
}
}
#endif
static inline CGFloat CGPointToPixel(UIView * _Nonnull view, CGFloat point) {
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION
return point * 2.0;
#else
UIScreen *screen = view.window.screen;
if (!screen) {
screen = [UIScreen mainScreen];
}
return point * screen.nativeScale;
return point * CGViewNativeScale(view);
#endif
}
@@ -89,10 +99,6 @@ static inline CGFloat CGPixelToPoint(UIView * _Nonnull view, CGFloat pixel) {
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION
return pixel / 2.0;
#else
UIScreen *screen = view.window.screen;
if (!screen) {
screen = [UIScreen mainScreen];
}
return pixel / screen.nativeScale;
return pixel / CGViewNativeScale(view);
#endif
}