(还是说我用的方法不对劲)
大概是在实现「需要回到上一页」的时候发现出现的问题。相关的页面大概是:根页面 - 分页 1 - 分页 2 这样的路径。先是在分页 2 里面实现提交数据后返回根页面,试了好几次都似乎没什么问题。回退就寄了。
NavigationLink 和 Button 里 removeLast 掉 path 都试过了。NavigationLink 可以回到根页面但下一次访问分页 1 的时候会大概率闪回根页面,运气好进入分页后再访问分页 2 一定会被闪回去。Button 的话,会出现第一次按下去无反应,第二次按下去的时候 crash 的情况。猜测此时的 path 为空。
不过有趣的地方在于如果 Button 按下的交互逻辑里包含一个数据增删的操作(也就是在 modelContext 里面添加或者删掉随便什么东西),removeLast 也是可以正常运行的。这时候就可以从分页 2 返回到根页面,然后再进入也不会出现奇怪的问题或者被闪回去。但总感觉有点面向 Bug 开发了。
感觉是很奇怪的现象,这几天把 stackoverflow 翻了个底朝天也没找到相关的描述。不知道跟这个相关的原理或者 issue 是什么,尤其是为啥随便加个 dummy data 反而看起来又能跑了呢。
以下为相关的按钮的写法,去掉了不相关的代码:
根页面里:
ToolbarItem {
NavigationLink(destination: SubPage1(pathManager: $pathManager)
.navigationBarBackButtonHidden(true),
label: {
Label("Add Item", systemImage: "square.and.pencil")
})
}
分页 1 里面再进一步的按钮:
Button {
let generated = SomeModel(...)
generated.someRelationship = ...
pathManager.path.append(generated)
} label: {
Label("Save", systemImage: "paperplane.fill")
}
.navigationDestination(for: SomeModel.self) { x in
SubPage2(pathManager: $pathManager, data: x)
.navigationBarBackButtonHidden(true)
}
.disabled(!incomplete)
分页 2 里面回根页面的按钮:
这个可以正常使用。
Button {
modelContext.insert(data)
let data2 = AnotherModel()
modelContext.insert(data2)
data2.someRelationship = ...
pathManager.path.removeLast()
} label: {
Label("Save", systemImage: "paperplane.fill")
}
这个就寄了。
Button {
pathManager.path.removeLast()
// 或者 removeLast(path.count),当然这种情况下就永远按不动
} label: {
Label("Discard", systemImage: "minus")
}
版本:Xcode 15.0.1 ,虚拟机是 17.0.1 的 iPhone 15 Pro ,本机是 Sonoma 14.1.1 。
1
alexcding 344 天前
你用到 NavigationStack 跟 NavigationPath, 就不要和 NavigationLink(destination:混用)
NavigationLink(destination: 是 iOS15 以及之前的, 用 NavigationLink(value), 或者直接 append path |
2
netabare OP @alexcding 感谢回复,稍微修复了一下,去掉`NavigationLink(destination:`后看起来可以通过`NavigationLink`进行正常导航了,也可以使用`presentationMode.wrapper.dismiss()`来去掉最后一页。
不过关于`path.removeLast`还是有前面提到的问题,也就是如果不进行数据库交互的话,第一次 removeLast 不会有任何反应,按多几次程序会崩溃。虽说可以用`NavigationLink`或者`presentationMode`的`dismiss`函数来绕过就是了…… |
3
alexcding 342 天前
你传个版本到 github, 我看一下. 这边看 code 太累
|