微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

需要有关使用 List 容器在 SwiftUI 中实现 NavigationView 的“pop to root”视图的帮助

如何解决需要有关使用 List 容器在 SwiftUI 中实现 NavigationView 的“pop to root”视图的帮助

我正在尝试实现一个 NavigationLinks 列表,它允许我在最多 3 级导航链接的视图之间导航。

主视图 -> 视图 2 -> 视图 3 -> 视图 4

当我到达 View4 时,该视图在导航栏中将没有认的“后退”按钮,而是有一个按钮可以让我导航回“主视图”

使用提到的解决方here,我能够(某种程度上)通过在解决方案中稍作修改来实现我想要的,以便将 isActive 位实现为一个 isActive 位的数组,每个位对应于数字在 List 容器内迭代的导航链接

我注意到的唯一问题是,使用 isActive 位的 pop-to-root 视图操作仅在我将它与 @State 属性包装器一起使用时才有效,但如果我的 isActive 位包含在 ObservableObject 中,则不会执行任何操作类实例。我使用 @State 包装器的问题是我必须预先定义一个固定的数组大小并用“false”位填充它,这不是我想要的,因为我可以在 List 容器中迭代的项目数量可能会有所不同所以我希望 isActive 数组大小与我在 List 容器中迭代的项目数相同。

这里是pop-to-root NavigationView代码的简化实现,供参考。 NavigationLinks 的上半部分使用固定大小的 isActive 位数组和 @State 包装器工作,而 NavigationLinks 的下半部分使用 observable 对象,它可以具有灵活的 isActive 位数组大小但我似乎无法弄清楚为什么这种方法不起作用。

主视图:

struct ContentView: View {
    @Observedobject var itemGroup: ItemGroup
    // If I use @State wrapper,I need to pre allocate a fixed array size and populate
    // it with 'false' values. 
    @State var isActive: [Bool] = [false,false,false]
    
    var body: some View {
        NavigationView {
            vstack {
                
            // MARK: Navigation links using isActive property with @State wrapper 
            // (this implementation works but the isActive array size needs to be defined
            // with a fixed size,I would prefer the size to be variable)
            List(1..<5) { item in
                NavigationLink(destination: View2(isActive: $isActive[item-1],sub: "sub\(item)"),isActive: $isActive[item-1]) {
                    Text("Go to view 2 using @State,sub\(item)")
                        .padding()
                        .background(Color.blue)
                        .foregroundColor(.white)
                }
            }
            
            // MARK: Navigation links using isActive property defined within an observable 
            // class object 
            // (I would have preferred this method since I can have the
            // flexibility of allocating an isActive array based on the number of
            // NavigationLink views generated by the list container but the pop-to-root
            // operation won't work with this approach)
            //  Note: The range 1..<5 is used here for illustration purposes only but is actually an array of objects whose array size may vary
            List(1..<5) { item in
                NavigationLink(destination: View2(isActive: $itemGroup.isActive[item-1],isActive: $itemGroup.isActive[item-1]) {
                    Text("Go to view 2,sub\(item)")
                        .padding()
                        .background(Color.blue)
                        .foregroundColor(.white)
                }
            }
            .navigationBarTitle("Main view")
            }   
        }   
    }
}

class ItemGroup: ObservableObject {
    @Published var isActive: [Bool] = []
    
    init() {
        //  Note: The range 1..<5 is used only for illustration purposes only.
        //        In my use case,this is actually an array of objects whose array size may vary.
        for _ in 1..<5 {
            isActive.append(false)
        }
    }
}

视图 2:

struct View2: View {
    @Binding var isActive: Bool
    @State var sub: String
    var body: some View {
        NavigationLink(destination: View3(isActive: $isActive)) {
            Text("Go to view 3")
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
        }
        .navigationBarTitle("View 2,\(sub)")
    }
}

视图 3:

struct View3: View {
    @Binding var isActive: Bool
    var body: some View {
        NavigationLink(destination: View4(isActive: $isActive)) {
            Text("Go to view 4")
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
        }
        .navigationBarTitle("View 3")
    }
}

View4(这是具有弹出到根视图功能的视图):

struct View4: View {
    @Binding var isActive: Bool
    
    var body: some View {
        vstack {
            Text("View 4")
            Button("Back to Main View",action: {
                isActive = false
            })
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
        }
        .navigationBarHidden(true)
    }
}

以下是两种不同实现的 gif 演示。

Navigation using isActive array with @State property wrapper (Click link)

Navigation using isActive array within an observable object (Click link)

谁能帮我弄清楚为什么 NavigationLinks 的下半部分不起作用,我应该做哪些更改才能使其正常工作?

感谢您的帮助。谢谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。