疑似发现了 Swift 的 NavigationStack 和 NavigationPath 的 bug? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
netabare
V2EX    iOS

疑似发现了 Swift 的 NavigationStack 和 NavigationPath 的 bug?

  •  
  •   netabare 2023-11-30 04:24:56 +08:00 1770 次点击
    这是一个创建于 747 天前的主题,其中的信息可能已经有所发展或是发生改变。

    (还是说我用的方法不对劲)

    大概是在实现「需要回到上一页」的时候发现出现的问题。相关的页面大概是:根页面 - 分页 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 。

    5 条回复    2023-12-12 01:50:10 +08:00
    alexcding
        1
    alexcding  
       2023-11-30 08:26:06 +08:00
    你用到 NavigationStack 跟 NavigationPath, 就不要和 NavigationLink(destination:混用)
    NavigationLink(destination: 是 iOS15 以及之前的, 用 NavigationLink(value), 或者直接 append path
    netabare
        2
    netabare  
    OP
       2023-12-01 23:26:17 +08:00   1
    @alexcding 感谢回复,稍微修复了一下,去掉`NavigationLink(destination:`后看起来可以通过`NavigationLink`进行正常导航了,也可以使用`presentationMode.wrapper.dismiss()`来去掉最后一页。

    不过关于`path.removeLast`还是有前面提到的问题,也就是如果不进行数据库交互的话,第一次 removeLast 不会有任何反应,按多几次程序会崩溃。虽说可以用`NavigationLink`或者`presentationMode`的`dismiss`函数来绕过就是了……
    alexcding
        3
    alexcding  
       2023-12-02 04:05:41 +08:00
    你传个版本到 github, 我看一下. 这边看 code 太累
    netabare
        4
    netabare  
    OP
       2023-12-10 01:10:55 +08:00   1
    @alexcding 应该是这个,链接 base64 了一下:
    aHR0cHM6Ly9naXRodWIuY29tL2tva29yby1heWEvYXNhZ2lyaS9ibG9iLzlhNmMyMGJjMzgxNGZiMjhhNDBmNmY0ZDI4OTI1YjdlNmNjOTE5Y2QvYXNhZ2lyaS9WaWV3cy9DcmVhdGVOZXdBcHBsaWNhdGlvblZpZXcuc3dpZnQjTDE0MQ==

    136-139 行的 dummy data 去掉的话就无法跳转+第二次点击时 crash 掉。
    alexcding
        5
    alexcding  
       2023-12-12 01:50:10 +08:00   1
    @netabare
    好像苹果是建议
    path.removeLast(path.count)

    其实输入新表格, 你用 sheet 比较好. 或者 fullscreencover 比较好.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3155 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 12:08 PVG 20:08 LAX 04:08 JFK 07:08
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86