使用 iOS 14 @main 时的托管控制器

dav*_*eme 9 swiftui

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

以前在SceneDelegate我有代码会说这样的话:

let contentView = ContentView()
window.rootViewController = UIHostingController(rootView: contentView)
Run Code Online (Sandbox Code Playgroud)

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

var body: some Scene {
    WindowGroup {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Asp*_*eri 6

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

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) {
    }
}
Run Code Online (Sandbox Code Playgroud)


pry*_*oax 6

我面临着同样的问题。我尝试了一种零设置的替代解决方案,这意味着它可以与 SwiftUI App 和 Playgrounds 一起使用(我什至编写了一组 Playgrounds 用于文档) - 该包称为SwiftUIWindowBinder

使用示例WindowBinder... 请参阅文档了解其他用法,例如事件视图修饰符(如onTapGesture),或WindowButton.

import SwiftUI
import SwiftUIWindowBinder

struct ContentView : View {
    /// Host window state (will be bound)
    @State var window: Window?

    var body: some View {
        // Create a WindowBinder and bind it to the state property `window`
        WindowBinder(window: $window) {
          
            Text("Hello")
                .padding()
                .onTapGesture {
                    guard let window = window else {
                        return
                    }

                    print(window.description)
                }
          
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该包的唯一警告是您不能使用主机窗口来构建视图。我有一个完整的 Playground页面


Cor*_*ken 0

这取决于您想要更改的内容,但您可以在ContentView .statusBar(hidden: true). 这也可以放置在应用程序的某些部分,在特定情况下隐藏可能有意义。

本文列出了所有可用的新修饰符。https://medium.com/better-programming/swiftui-views-and-controls-the-swift-2-documentation-youve-been-waiting-for-dfa32cba24f3#6299