本文介绍了使用 iOS 14 @main 时的托管控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在试验一个纯"的 SwiftUI 应用.它没有 SceneDelegate,所以我不确定在 iOS 上运行时我需要的 Hosting Controller 东西放在哪里.

I’m experimenting with a "pure" SwiftUI app. It doesn’t have a SceneDelegate so I’m unsure of where to put Hosting Controller stuff that I need for when it’ll be running on iOS.

以前在 SceneDelegate 中,我的代码会这样说:

Previously in the SceneDelegate I’d have code that would say something like:

let contentView = ContentView()
window.rootViewController = UIHostingController(rootView: contentView)

现在我只有一个 @main 文件:

Now I just have an @main file with:

var body: some Scene {
    WindowGroup {
        ContentView()
    }
}

那么 Hosting Controller 的东西去哪里了(或者我如何才能访问 SwiftUI 没有的 UIKit 功能?(具体来说,我想弄乱状态栏,自动隐藏主页指示器,以及一些关于SwiftUI 的 preferredColorScheme 未涵盖的亮/暗模式.)

So where does the Hosting Controller stuff go (or how else can I access UIKit features that SwiftUI doesn’t have? (Specifically, I want to mess with the status bar, auto hiding the home indicator, and a few things about light/dark mode that SwiftUI’s preferredColorScheme doesn’t cover.)

推荐答案

这是一种可能的方法(使用 Xcode 12/iOS 14 测试)...但如果您打算大量使用 UIKit 功能,最好使用 UIKit Life-Cycle,因为它为配置 UIKit 部分提供了更大的灵活性.

Here is a possible approach (tested with Xcode 12 / iOS 14)... but if you intend to use UIKit features heavily it is better to use UIKit Life-Cycle, as it gives more flexibility to configure UIKit part.

struct ContentView: View {

    var body: some View {
      Text("Demo Root Controller access")
        .withHostingWindow { window in
            if let controller = window?.rootViewController {
                // .. do something with root view controller
            }
        }
    }
}

extension View {
    func withHostingWindow(_ callback: @escaping (UIWindow?) -> Void) -> some View {
        self.background(HostingWindowFinder(callback: callback))
    }
}

struct HostingWindowFinder: UIViewRepresentable {
    var callback: (UIWindow?) -> ()

    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        DispatchQueue.main.async { [weak view] in
            self.callback(view?.window)
        }
        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {
    }
}

这篇关于使用 iOS 14 @main 时的托管控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 01:19