iOS16+替代UIScreen.main获取屏幕尺寸的非GeometryReader方案
iOS16+ 无需GeometryReader获取屏幕宽高的替代方案
针对UIScreen.main的弃用警告,这里提供两种不需要GeometryReader的适配方案,均适配iOS16及以上版本:
方案一:通过UIApplication获取当前活跃屏幕(推荐)
利用UIApplication的connectedScenes获取当前处于活跃状态的窗口场景,进而拿到对应屏幕的尺寸信息,完全避开弃用的UIScreen.main。
步骤1:封装屏幕获取工具
先写一个扩展,方便快速获取当前活跃屏幕:
import UIKit extension UIScreen { static var current: UIScreen? { // 过滤出当前活跃的前景窗口场景 let activeScene = UIApplication.shared.connectedScenes .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene return activeScene?.screen } }
步骤2:在视图中动态获取尺寸
将原来的静态属性改为@State变量,在视图出现时获取屏幕尺寸,同时监听屏幕变化(比如旋转)自动更新:
struct ContentView: View { @State private var width: CGFloat = 0 @State private var height: CGFloat = 0 var fontSize: CGFloat var body: some View { // 这里正常使用width和height布局即可 ExampleView() .onAppear { updateScreenSize() } .onChange(of: UIScreen.current?.bounds) { _ in updateScreenSize() } } private func updateScreenSize() { guard let screen = UIScreen.current else { return } width = screen.bounds.width height = screen.bounds.height } // 示例视图,仅作演示 @ViewBuilder private func ExampleView() -> some View { Text("屏幕宽:\(width) | 屏幕高:\(height)") .font(.system(size: fontSize)) } }
方案二:通过视图的windowScene间接获取
如果需要在视图初始化阶段就拿到尺寸(不推荐,因为初始化时视图可能还未关联到窗口),可以通过UIViewRepresentable获取当前视图所在的windowScene:
struct ScreenSizeReader: UIViewRepresentable { var onSizeUpdate: (CGFloat, CGFloat) -> Void func makeUIView(context: Context) -> UIView { let view = UIView() DispatchQueue.main.async { if let screen = view.window?.windowScene?.screen { onSizeUpdate(screen.bounds.width, screen.bounds.height) } } return view } func updateUIView(_ uiView: UIView, context: Context) {} } // 在ContentView中使用 struct ContentView: View { @State private var width: CGFloat = 0 @State private var height: CGFloat = 0 var fontSize: CGFloat var body: some View { ZStack { // 隐藏的尺寸读取器 ScreenSizeReader { w, h in width = w height = h } // 你的业务视图 Text("屏幕宽:\(width) | 屏幕高:\(height)") .font(.system(size: fontSize)) } } }
注意事项
- 方案一的
onAppear和onChange组合能覆盖绝大多数场景,包括屏幕旋转、多窗口切换等动态变化。 - 避免在视图结构体初始化时直接获取屏幕尺寸,此时视图还未绑定到具体窗口场景,容易拿到错误的信息。
内容的提问来源于stack exchange,提问作者abs8090
相关产品推荐
相关产品推荐

