prefersHomeIndicatorAutoHidden

prefersHomeIndicatorAutoHidden

在SwiftUI中,相当于UIKit的prefersHomeIndicatorAutoHidden属性是什么?

最佳答案

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

我想要的是:

var body: some View {
    Text("I hide my home indicator")
        .prefersHomeIndicatorAutoHidden(true)
}

由于prefersHomeIndicatorAutoHidden是UIViewController的属性,因此我们可以在UIHostingController中覆盖它,但是我们需要从prefersHomeIndicatorAutoHidden设置 View 层次结构,将其设置为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)
    }
}

现在,如果我们在 View 上添加.prefersHomeIndicatorAutoHidden(true),它将在 View 层次结构中发送PrefersHomeIndicatorAutoHiddenPreferenceKey。为了在托管 Controller 中了解到这一点,我制作了一个子类,该子类包装了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
    }
}

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

10-08 11:53