0

I have a iOS app that uses a library. This library used to have problems when the iOS or iPadOS device or simulator was set to be in Zoom mode in the system settings. The developer of the library has provided a fix, but he has told me that in order to benefit from the fix, I have to use UIScreen nativeScale instead of scale. I tried to solve the problem without affecting the rest of the project code by declaring an extension like this:

extension UIScreen {

    open var scale: CGFloat {
        get {
            return nativeScale
        }
    }
}

This works, but I would like somehow to make this extension effective only when the device is set to zoom mode. I have found a way to detect that, but now I don't know how to proceed. I am aware that I cannot access the scale property from within its getter, so I was wondering if there is a possible implementation to achieve that. Thanks for your attention.

Alfonso Tesauro
  • 1,730
  • 13
  • 21

1 Answers1

0

The comment from Cristik made me think of a solution. Cristik asked for the code to detect Zoom mode. I have found a good implementation in the DeviceKit repository. The solution is the following:

public var isZoomed: Bool? {
    guard isCurrent else { return nil }
    if Int(UIScreen.main.scale.rounded()) == 3 {
      // Plus-sized
      return UIScreen.main.nativeScale > 2.7 && UIScreen.main.nativeScale < 3
    } else {
      return UIScreen.main.nativeScale > UIScreen.main.scale
    }
}

To achieve my goal, I added to DeviceKit this property:

public var originalDeviceScale: CGFloat? {
    guard isCurrent else { return nil }
  
    return UIScreen.main.scale
}

Being in a completely different target, my extension to UIScreen in the main project does not apply, so I can now write:

import UIKit
import DeviceKit

extension UIScreen {

    open var scale: CGFloat {
        get {
        
            let device = Device()
        
            guard let isZoomed = device.isZoomed else {
                return -1
            }
        
            if isZoomed {
                return nativeScale
            }
        
           guard let originalDeviceScale = device.originalDeviceScale else {
              return -1
           }
        
        return originalDeviceScale
    }
}

If you are not using DeviceKit, you could add a static library target to your project containing just the originalNativeScale property. I understand this is not a complete solution but could be possibly useful to others. Thanks for your attention.

Alfonso Tesauro
  • 1,730
  • 13
  • 21