You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 16后如何替代已废弃的UIScreen.main.scale?

替代废弃的UIScreen.main.scale的方案(含应用扩展兼容)

iOS 16 之后,UIScreen.main.scale 已被废弃,UIKit 中 UIScreen 的文档标注如下:

@available(iOS, introduced: 2.0, deprecated: 100000, message: "Use a UIScreen instance found through context instead: i.e, view.window.windowScene.screen")
open class var main: UIScreen { get } // the device's internal screen

其中deprecated: 100000表示该API已被废弃。现有主应用可行的替代方案依赖UIApplication.shared,无法在应用扩展中使用,以下是分场景的解决方案:

一、主应用中的替代实现

你提供的代码可以在主应用中正常获取当前屏幕,但因依赖UIApplication.shared,无法在应用扩展中运行:

@available(iOSApplicationExtension, unavailable)
extension UIWindow {
    static var current: UIWindow? {
        for scene in UIApplication.shared.connectedScenes {
            guard let windowScene = scene as? UIWindowScene else { continue }
            for window in windowScene.windows {
                if window.isKeyWindow { return window }
            }
        }
        return nil
    }
}

@available(iOSApplicationExtension, unavailable)
extension UIScreen {
    static var current: UIScreen? {
        UIWindow.current?.screen
    }
}

使用时通过UIScreen.current?.scale即可获取屏幕缩放比例。

二、兼容应用扩展的解决方案

应用扩展无法访问UIApplication.shared,需根据扩展类型从上下文获取UIScreen实例:

1. 带视图的扩展(如今日小组件、自定义键盘)

如果扩展包含视图,直接从视图上下文获取:

extension UIView {
    var screenScale: CGFloat {
        self.window?.windowScene?.screen.scale ?? UIScreen.main.scale // 兼容旧系统降级
    }
}

调用示例:yourView.screenScale

2. 无视图的扩展(如分享扩展、动作扩展)

这类扩展可通过NSExtensionContext获取关联场景,或降级使用旧API(苹果允许扩展中暂时沿用,直到推出替代方案):

// 获取屏幕缩放比例
let scale: CGFloat = {
    if let scene = NSExtensionContext.shared?.scene as? UIWindowScene {
        return scene.screen.scale
    }
    // 降级到旧API
    return UIScreen.main.scale
}()

3. 通用兼容封装

可以封装一个工具类,自动适配主应用和扩展环境:

enum ScreenScaleProvider {
    static var scale: CGFloat {
        // 判断是否为扩展环境
        let isExtension = Bundle.main.bundlePath.hasSuffix(".appex")
        
        if !isExtension {
            // 主应用环境
            return UIWindow.current?.screen.scale ?? UIScreen.main.scale
        } else {
            // 扩展环境
            if let scene = NSExtensionContext.shared?.scene as? UIWindowScene {
                return scene.screen.scale
            }
            return UIScreen.main.scale
        }
    }
}

// 主应用中复用你之前的UIWindow扩展
@available(iOSApplicationExtension, unavailable)
extension UIWindow {
    static var current: UIWindow? {
        for scene in UIApplication.shared.connectedScenes {
            guard let windowScene = scene as? UIWindowScene else { continue }
            for window in windowScene.windows {
                if window.isKeyWindow { return window }
            }
        }
        return nil
    }
}

@available(iOSApplicationExtension, unavailable)
extension UIScreen {
    static var current: UIScreen? {
        UIWindow.current?.screen
    }
}

使用时直接调用ScreenScaleProvider.scale即可在主应用和扩展中通用。

内容的提问来源于stack exchange,提问作者violethill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:33:12