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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:25:30