iOS邮件应用程序启动时,您最近查看的邮箱已经被推送到导航堆栈上,尽管它实际上是一个详细的屏幕,根视图控制器是所有邮箱的列表。这在UIKit中是很简单的,因为推到导航控制器上是很简单的,并且可以在viewDidLoad或applicationDidFinishLaunching内部完成。
NavigationView和NavigationLink是在SwiftUI中执行导航推送/pops的API,NavigationLink支持几个模仿编程导航的APIs -但我不太清楚如何能够支持这个特定的用例。每次屏幕出现时都会调用onAppear闭包(更像viewDidAppear而不是viewDidLoad),因此当用户试图弹出时,设置对应于NavigationLink的selection值将导致重复推送详细信息屏幕。我可以尝试对State进行一些黑客操作,以确定屏幕是否刚刚被查看过,但这似乎不太理想。(关于NavigationLink的selection API,我也遇到了一些问题,但这可能是另一个问题。)
有什么建议吗?我如何将应用程序启动到一个详细的屏幕上,但如果没有任何编程干预,NavigationView就能正常运行吗?
发布于 2021-03-10 22:34:36
如果不需要在模式或动画中显示视图,则应该使用编程导航( NavigationLink with selection binding )获得所需的行为。
例如,如果它是应用程序的根,那么下面的内容应该可以工作:
struct Item: Identifiable {
let id: Int
let name: String
}
struct NormalNav: View {
@State var items: [Item] = [
.init(id: 0, name: "One"),
.init(id: 1, name: "Two"),
.init(id: 2, name: "Three")
]
@State private var selection: Int? = 1
var body: some View {
NavigationView {
List {
ForEach(items) { item in
NavigationLink(item.name,
destination: Text(item.name),
tag: item.id,
selection: $selection)
}
}
}
}
}上面的视图应该直接打开到没有动画的第二项(“两个”)。
不过,还是有皱纹的。如果您需要在工作表中显示此视图,则使用动画推送详细视图,这可能不是您想要的结果。
在this answer的基础上,您可以在初始创建过程中禁用动画,但将其打开以供后续导航:
struct ContentView: View {
@State var items: [Item] = [
.init(id: 0, name: "One"),
.init(id: 1, name: "Two"),
.init(id: 2, name: "Three")
]
@State private var selection: Int? = nil
@State var isAnimationDisabled = true
@State var isListPresented = false
var body: some View {
Button("Show list") {
isListPresented = true
}.sheet(isPresented: $isListPresented) {
NavigationView {
List {
ForEach(items) { item in
NavigationLink(item.name,
destination: Text(item.name),
tag: item.id,
selection: $selection)
}
}.animations(disabled: isAnimationDisabled)
}.onChange(of: selection) { value in
if value == nil {
isAnimationDisabled = false
}
}.onAppear {
selection = 1
}
}
}
}
extension View {
func animations(disabled: Bool) -> some View {
transaction { (tx: inout Transaction) in
guard disabled else {
return
}
tx.disablesAnimations = true
tx.animation = .none
}
}
}https://stackoverflow.com/questions/66395168
复制相似问题