带有 `isActive=true` 的嵌套 NavigationLinks 未正确显示

Posted

技术标签:

【中文标题】带有 `isActive=true` 的嵌套 NavigationLinks 未正确显示【英文标题】:Nested NavigationLinks with `isActive=true` are not displaying correctly 【发布时间】:2021-09-22 16:57:35 【问题描述】:

我已经开始学习 SwiftUI,但是在构建 NavigationView 时遇到了一些问题 - 我不确定这是否是一个错误,或者我是否误解了嵌套导航链接的工作原理!

这是我当前的代码:

import SwiftUI

struct ContentView: View 
  var body: some View 
    NavigationView 
      ViewOne()
    
  


struct ViewOne: View 
  @State var isActiveOne: Bool = true

  var body: some View 
    VStack 
      Text("View One")
      
      NavigationLink(
        destination: ViewTwo(),
        isActive: $isActiveOne,
        label:  EmptyView() 
      )
      
      Button(
        action:  self.isActiveOne = true ,
        label:  Text("Set isActiveOne=true") 
      )
    
  


struct ViewTwo: View 
  @State var isActiveTwo: Bool = true

  var body: some View 
    VStack 
      Text("View Two")
      
      NavigationLink(
        destination: Text("Success!"),
        isActive: $isActiveTwo,
        label:  EmptyView() 
      )

      Button(
        action:  self.isActiveTwo = true ,
        label:  Text("Set isActiveTwo=true") 
      )
    
  


struct ContentView_Preview: PreviewProvider 
  static var previews: some View 
    ContentView()
  

我希望:

NavigationView 显示 ViewOne ViewOne 具有 isActiveOne == true,因此会显示第一个 NavigationLink 目标(显示 ViewTwo) ViewTwo 具有 isActiveTwo == true,因此会显示第二个 NavigationLink 目标(显示“成功!”)

但是,当我在 ios 14.5 模拟器上运行此代码时,第二个 NavigationLink 不会自动显示(我只看到 ViewTwo Button 文本)。

我还觉得奇怪的是,如果我默认 isActiveTrue 为 false,然后按下按钮,它会正确导航 - 默认“true”状态 + 嵌套导航链接的组合似乎是导致问题的原因。

知道这是否是 SwiftUI 中的错误?还是我在这里的设置做错了什么?

任何想法都会是一个巨大的帮助 - 我已经把头撞在墙上一段时间了......

【问题讨论】:

【参考方案1】:

这看起来像一个错误,你可以在https://feedbackassistant.apple.com提交它

临时解决方法是将您的NavigationLinks 放入列表中。这似乎适用于 iOS 14.5 和 15(beta 2)

不可见列表

如果您不想要列表的行为/外观,那么您可以将列表放在背景上并使其透明(使用 opacity 修饰符)

以下是不可见列表解决方法的示例:

struct WorkaroundLink<Destination: View>: View 
    let destination: Destination
    let isActive: Binding<Bool>

    var body: some View 
        List 
            NavigationLink(
                destination: destination,
                isActive: isActive,
                label:  EmptyView() 
            )
        .opacity(0.01)
    


extension View 
    func workaroundLink<D: View>(to destination: D, isActive: Binding<Bool>) -> some View 
        background(WorkaroundLink(destination: destination, isActive: isActive))
    

用这个结构重写你的例子变成:

struct ContentView: View 
    var body: some View 
        NavigationView  ViewOne() 
    


struct ViewOne: View 
    @State var isActiveOne = true

    var body: some View 
        VStack 
            Text("View One")
            Button("Set isActiveOne=true")  isActiveOne = true 
        .workaroundLink(to: ViewTwo(), isActive: $isActiveOne)
    


struct ViewTwo: View 
    @State var isActiveTwo = true
    var body: some View 
        VStack 
            Text("View Two")

            Button(
                action:  self.isActiveTwo = true ,
                label:  Text("Set isActiveTwo=true") 
            )
        .workaroundLink(to: Text("Success!"), isActive: $isActiveTwo)
    

【讨论】:

感谢达米安的推荐!我已经通过反馈助手 [FB9321916] 提交了一个错误。不幸的是,列表似乎不适用于我的情况(除非有某种方法可以完全隐藏它?) - 我希望以编程方式管理所有路由......我会花一些时间调查,看看是否有一些我的情况的其他解决方法。谢谢! 是的,有一种(有点笨拙的)方法可以(几乎)完全隐藏列表。请参阅我的更新答案。 啊 - 创造性的解决方法!感谢您返回并添加更新的示例 - 非常感谢! :)

以上是关于带有 `isActive=true` 的嵌套 NavigationLinks 未正确显示的主要内容,如果未能解决你的问题,请参考以下文章

iOS 约束样式:addConstraints vs .isActive = true

带有嵌套 SQL 查询或如何查找最后一个 INET 的 Postgres 视图

vue 绑定class的方式

如何在pyspark中按字母顺序对嵌套结构的列进行排序?

vue-03-style与class

使用路由器 Vuetify 选项卡 - tab.isActive 始终为 false