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

SwiftUI中无需AppDelegate/SceneDelegate锁定竖屏方向的实现方案

SwiftUI 锁定屏幕方向(适配新项目无Scene/AppDelegate场景)

问题根源

你用的UIDevice.current.setValue(...)是苹果早已弃用的私有调用方式,直接触发了UIKit的BUG警告;而且基于WindowGroup的SwiftUI新项目,方向控制逻辑已经从旧的AppDelegate/SceneDelegate转移到了每个UIWindowScene,原来的supportedInterfaceOrientationsFor方法已经失效。

解决方案

1. 封装方向管理工具类

先写个工具类统一处理方向锁定,避免代码混乱:

import UIKit

enum OrientationLock {
    case portrait
    case landscapeLeft
    case landscapeRight
    case all
}

class OrientationManager {
    static func lock(to orientation: OrientationLock) {
        guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }
        
        let supportedOrientations: UIInterfaceOrientationMask
        let preferredOrientation: UIInterfaceOrientation
        
        switch orientation {
        case .portrait:
            supportedOrientations = .portrait
            preferredOrientation = .portrait
        case .landscapeLeft:
            supportedOrientations = .landscapeLeft
            preferredOrientation = .landscapeLeft
        case .landscapeRight:
            supportedOrientations = .landscapeRight
            preferredOrientation = .landscapeRight
        case .all:
            supportedOrientations = .all
            preferredOrientation = .portrait // 默认优先竖屏
        }
        
        // 设置当前场景允许的方向
        windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: supportedOrientations))
        
        // 强制切换到目标方向
        UIScreen.main.setOrientation(preferredOrientation)
    }
}

// 给UIScreen加扩展,处理方向切换
extension UIScreen {
    func setOrientation(_ orientation: UIInterfaceOrientation) {
        guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }
        let orientationInfo = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: [orientation])
        windowScene.requestGeometryUpdate(orientationInfo)
    }
}

2. 在View中调用锁定逻辑

修改你的ContentView,删掉旧的UIDevice调用,改用上面的工具类:

import SwiftUI

struct ContentView: View {
    var body: some View {
        ZStack {
            // 你的页面内容写在这里
            Text("锁定竖屏测试")
                .font(.largeTitle)
        }
        .onAppear {
            // 锁定为竖屏,需要其他方向改对应的枚举值即可
            OrientationManager.lock(to: .portrait)
        }
        .onDisappear {
            // 可选:离开页面时恢复所有方向支持
            // OrientationManager.lock(to: .all)
        }
    }
}

3. 配置Info.plist(必须)

确保你的Info.plist里已经添加了需要支持的方向(项目默认会带,但最好检查下):

  • 找到UISupportedInterfaceOrientations,添加你需要的方向(比如Portrait、Landscape Left等)
  • iPad端对应UISupportedInterfaceOrientations~ipad,同理配置

核心说明

  • 全程用苹果官方推荐的UIWindowScene.requestGeometryUpdate方法,完全避开私有API,不会触发警告。
  • 适配多窗口场景(比如iPad分屏),每个UIWindowScene独立管理方向。
  • 工具类封装后,在任意View里都能快速调用,逻辑清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:47:19