问题描述
与 SwiftUI 中的 prefersHomeIndicatorAutoHidden
属性等效的 UIKit 是什么?
What's the UIKit equivalent of the prefersHomeIndicatorAutoHidden
property in SwiftUI?
推荐答案
由于我在默认 API 中也找不到这个,所以我自己在 UIHostingController 的一个子类中做了它.
Since I could't find this in the default API either, I made it myself in a subclass of UIHostingController.
我想要的:
var body: some View {
Text("I hide my home indicator")
.prefersHomeIndicatorAutoHidden(true)
}
由于 prefersHomeIndicatorAutoHidden
是 UIViewController 上的一个属性,我们可以在 UIHostingController 中覆盖它,但我们需要从我们设置的视图中获取设置视图层次结构的 prefersHomeIndicatorAutoHidden
将它放到 UIHostingController 中的 rootView 上.
Since the prefersHomeIndicatorAutoHidden
is a property on UIViewController we can override that in UIHostingController but we need to get the prefersHomeIndicatorAutoHidden
setting up the view hierarchy, from our view that we set it on to the rootView in UIHostingController.
我们在 SwiftUI 中这样做的方式是 PreferenceKeys.网上有很多很好的解释.
The way that we do that in SwiftUI is PreferenceKeys. There is lots of good explanation on that online.
所以我们需要一个 PreferenceKey 来将值发送到 UIHostingController:
So what we need is a PreferenceKey to send the value up to the 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)
}
}
现在,如果我们在视图上添加 .prefersHomeIndicatorAutoHidden(true)
,它会将 PrefersHomeIndicatorAutoHiddenPreferenceKey 向上发送到视图层次结构.为了在托管控制器中捕获它,我创建了一个子类来包装 rootView 以监听首选项更改,然后更新 UIViewController.prefersHomeIndicatorAutoHidden
:
Now if we add .prefersHomeIndicatorAutoHidden(true)
on a View it sends the PrefersHomeIndicatorAutoHiddenPreferenceKey up the view hierarchy. To catch that in the hosting controller I made a subclass that wraps the rootView to listen to the preference change, then update the 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
Full example that doesn't expose the PreferenceKey type and has preferredScreenEdgesDeferringSystemGestures
too on git: https://gist.github.com/Amzd/01e1f69ecbc4c82c8586dcd292b1d30d
这篇关于如何使用 SwiftUI 隐藏主页指示器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!