swiftui - 为根 NavigationView 应用基于 HorizontalSizeClass 的 navigationStyle 并保留导航堆栈
问题描述
在应用程序启动时,我想获得 HorizontalSizeClass 并根据它是紧凑的还是常规的,将导航样式应用于我的根导航视图,如下所示:
import SwiftUI
@main
struct MyApp: App {
@Environment(\.horizontalSizeClass) var sizeClass
var body: some Scene {
WindowGroup {
if sizeClass == .compact {
NavigationView {
Text("Compact size class inside stack navigation style")
}
.navigationViewStyle(StackNavigationViewStyle())
} else {
NavigationView {
Text("Regular size class inside default navigation style")
}
}
}
}
}
但是,在这种情况下sizeClass
总是返回。nil
我如何能
- 确定水平尺寸类在根视图上是紧凑的还是规则的,以及
- 使导航样式在任何时候都适应大小类
我的应用程序针对 iPhone 和 iPad 的 iOS 14。
非常感谢任何帮助或适应整个应用程序大小类更改的不同方法。
更新 1
我尝试了使用ViewModifier
或创建自定义视图并在其正文中添加导航的建议,如下所示:
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
MyRootView()
}
}
}
struct MyRootView: View {
@Environment(\.horizontalSizeClass) var sizeClass
var body: some View {
if sizeClass == .compact {
NavigationView {
Text("Compact size class inside stack navigation style")
}
.navigationViewStyle(StackNavigationViewStyle())
} else {
NavigationView {
Text("Regular size class inside default navigation style")
}
}
}
}
但是,每次sizeClass
更改时,导航堆栈都会弹出到根视图。有没有办法保留堆栈?例如:如果用户在导航中的深度为 5 级,并且sizeClass
更改,更改导航样式同时保持可见屏幕?
谢谢!
更新 2
我能够找到一个 WWDC 会话来解释我想要什么,但它在 UIKit 中。
请参阅此处的 18:35:https ://developer.apple.com/wwdc20/10105
我正在尝试在 SwiftUI 中实现相同的目标(在将尺寸类更改为紧凑时保持用户选择的屏幕)。
根据会议,UISplitViewController
支持这一点,因为在详细视图中有Restorable
and的概念。Restore
我找不到在 SwiftUI 中执行此操作的方法。
解决方案
是的,忘记了导航视图。您可以尝试这样的事情(使用“https://matteo-pucinelli.medium.com/conditionally-apply-modifiers-in-swiftui-51c1cf7f61d1”中的代码)
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
extension View {
@ViewBuilder
func ifCondition<TrueContent: View, FalseContent: View>(_ condition: Bool, then trueContent: (Self) -> TrueContent, else falseContent: (Self) -> FalseContent) -> some View {
if condition {
trueContent(self)
} else {
falseContent(self)
}
}
}
struct ContentView: View {
@Environment(\.horizontalSizeClass) var sizeClass
var body: some View {
NavigationView {
if sizeClass == .compact {
Text("Compact size class inside stack navigation style")
} else {
Text("Regular size class inside default navigation style")
}
}
.ifCondition(sizeClass == .compact) { nv in
nv.navigationViewStyle(StackNavigationViewStyle())
} else: { nv in
nv.navigationViewStyle(DefaultNavigationViewStyle())
}
}
}
推荐阅读
- javascript - Nativescript 通过代码添加 ScrollView (Javascript)
- php - API Blogger - 在移动设备上显示图像
- php - 在 Wordpress 中使用 AJAX 提交的注册表单
- reactjs - 具有两个“主从”选择的 Formik
- android - adMob 测试广告无法在手机上运行,但可以在平板电脑上运行
- mysql - 计算具有特定评级mysql的餐厅
- linux - 如何在 Manjaro 上将 sysvinit 脚本转换为 systemd
- com - 注册 DirectshowFilter 将 InprocServer32 注册表项链接到 regsvr32.exe 而不是主机 DLL,我哪里出错了?
- html - 图像大小改进和 CSS 文件
- javascript - KnockoutJS - 可观察对象的可观察数组,包含来自 SQL 服务器的数据