我正在开发一个分形时钟应用程序,它在主视图中显示基于时钟指针的动画分形。我希望我的应用程序的用户能够进入全屏模式,在那里所有不必要的UI暂时隐藏,只有动画仍然可见。我正在寻找的行为类似于苹果的Photos应用程序,人们可以点击当前显示的图像,这样导航栏、底部条、状态栏和主指示器就会淡出,直到图像再次被点击。
隐藏导航栏和状态栏就像找到正确的视图修饰符来传递隐藏条件一样容易。但据我所知,目前SwiftUI不可能在不引入UIKit的情况下隐藏主指示器。
在堆栈溢出时,我找到了用于有条件隐藏主指示器的this solution by Casper Zandbergen,并将其用于我的项目。它起作用了,但不幸的是,它带来了一个不可接受的副作用:主视图现在不再扩展到状态栏和主指示器下面,这两种情况有两个含义:
我希望有不错的UIKit经验的人能帮我这个忙。请记住,我是SwiftUI的初学者,我基本上没有使用UIKit的经验。提前感谢!
import SwiftUI
struct ContentView: View {
@StateObject var settings = Settings()
@State private var showSettings = false
@State private var hideUI = false
var body: some View {
NavigationView {
GeometryReader { proxy in
let radius = 0.5 * min(proxy.size.width, proxy.size.height) - 20
FractalClockView(settings: settings, clockRadius: radius)
}
.ignoresSafeArea(.all)
.toolbar {
Button(
action: { showSettings.toggle() },
label: { Label("Settings", systemImage: "slider.horizontal.3") }
)
.popover(isPresented: $showSettings) { SettingsView(settings: settings) }
}
.navigationBarTitleDisplayMode(.inline)
.onTapGesture {
withAnimation { hideUI.toggle() }
}
.navigationBarHidden(hideUI)
.statusBar(hidden: hideUI)
.prefersHomeIndicatorAutoHidden(hideUI) // Code by Amzd
}
.navigationViewStyle(.stack)
}
}
发布于 2022-06-19 18:23:36
通过完全切换到基于故事板的项目模板,并按照SwiftUI中描述的那样,通过自定义UIHostingController嵌入视图,我能够解决UIHostingController视图不能扩展到状态栏和主指示器的安全区域内的问题。在我将托管控制器重新集成到SwiftUI视图层次结构之前,我用一个UIViewRepresentable实例包装了它,这肯定导致了处理安全区域的复杂性。
通过定制的UIHostingController子类来管理整个应用程序,可以更容易地隐藏家庭指示器。尽管我非常喜欢SwiftUI,但我不得不意识到,由于其目前的局限性,UIKit在这里是更好的选择。
最终代码(上述链接的解决方案的优化版本):
ViewController.swift
import SwiftUI
import UIKit
struct HideUIPreferenceKey: PreferenceKey {
static var defaultValue: Bool = false
static func reduce(value: inout Bool, nextValue: () -> Bool) {
value = nextValue() || value
}
}
extension View {
func userInterfaceHidden(_ value: Bool) -> some View {
preference(key: HideUIPreferenceKey.self, value: value)
}
}
class ViewController: UIHostingController<AnyView> {
init() {
weak var vc: ViewController? = nil
super.init(
rootView: AnyView(
ContentView()
.onPreferenceChange(HideUIPreferenceKey.self) {
vc?.userInterfaceHidden = $0
}
)
)
vc = self
}
@objc required dynamic init?(coder: NSCoder) {
weak var vc: ViewController? = nil
super.init(
coder: coder,
rootView: AnyView(
ContentView()
.onPreferenceChange(HideUIPreferenceKey.self) {
vc?.userInterfaceHidden = $0
}
)
)
vc = self
}
private var userInterfaceHidden = false {
didSet { setNeedsUpdateOfHomeIndicatorAutoHidden() }
}
override var prefersStatusBarHidden: Bool {
userInterfaceHidden
}
override var prefersHomeIndicatorAutoHidden: Bool {
userInterfaceHidden
}
}
https://stackoverflow.com/questions/70820790
复制相似问题