如何使用SwiftUI隐藏主页指示器?

Sco*_*tow 6 ios swift swiftui

prefersHomeIndicatorAutoHiddenSwiftUI 中的属性相当于UIKit 吗?

Moj*_*ini 9

iOS 16

您可以使用.persistentSystemOverlays和 传入来隐藏自动放置在我们的 UI 上的.hidden所有非瞬态系统视图

Text("Goodbye home indicator, the multitask indicator on iPad, and more.")
    .persistentSystemOverlays(.hidden)
Run Code Online (Sandbox Code Playgroud)


Cas*_*gen 8

由于我也无法在默认 API 中找到它,所以我自己在 UIHostingController 的子类中创建了它。

我想要的:

var body: some View {
    Text("I hide my home indicator")
        .prefersHomeIndicatorAutoHidden(true)
}
Run Code Online (Sandbox Code Playgroud)

由于prefersHomeIndicatorAutoHidden是 UIViewController 上的一个属性,我们可以在 UIHostingController 中覆盖它,但我们需要prefersHomeIndicatorAutoHidden设置视图层次结构,从我们将它设置到 UIHostingController 中的 rootView 的视图中。

我们在 SwiftUI 中这样做的方式是 PreferenceKeys。网上有很多很好的解释。

所以我们需要一个 PreferenceKey 来将值发送到 UIHostingController:

struct PrefersHomeIndicatorAutoHiddenPreferenceKey: PreferenceKey {
    typealias Value = Bool

    static var defaultValue: Value = false

    static func reduce(value: inout Value, nextValue: () -> Value) {
        value = nextValue() || value
    }
}

extension View {
    // Controls the application's preferred home indicator auto-hiding when this view is shown.
    func prefersHomeIndicatorAutoHidden(_ value: Bool) -> some View {
        preference(key: PrefersHomeIndicatorAutoHiddenPreferenceKey.self, value: value)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们添加.prefersHomeIndicatorAutoHidden(true)一个视图,它会将 PrefersHomeIndicatorAutoHiddenPreferenceKey 向上发送到视图层次结构。为了在托管控制器中捕获它,我创建了一个子类来包装 rootView 以侦听首选项更改,然后更新UIViewController.prefersHomeIndicatorAutoHidden

// Not sure if it's bad that I cast to AnyView but I don't know how to do this with generics
class PreferenceUIHostingController: UIHostingController<AnyView> {
    init<V: View>(wrappedView: V) {
        let box = Box()
        super.init(rootView: AnyView(wrappedView
            .onPreferenceChange(PrefersHomeIndicatorAutoHiddenPreferenceKey.self) {
                box.value?._prefersHomeIndicatorAutoHidden = $0
            }
        ))
        box.value = self
    }

    @objc required dynamic init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    private class Box {
        weak var value: PreferenceUIHostingController?
        init() {}
    }

    // MARK: Prefers Home Indicator Auto Hidden

    private var _prefersHomeIndicatorAutoHidden = false {
        didSet { setNeedsUpdateOfHomeIndicatorAutoHidden() }
    }
    override var prefersHomeIndicatorAutoHidden: Bool {
        _prefersHomeIndicatorAutoHidden
    }
}
Run Code Online (Sandbox Code Playgroud)

不公开 PreferenceKey 类型并且preferredScreenEdgesDeferringSystemGestures在 git 上也有的完整示例:https : //gist.github.com/Amzd/01e1f69ecbc4c82c8586dcd292b1d30d