首页 > 解决方案 > SwiftUI - 使用自定义绑定时 TabView/NavigationLink 导航中断

问题描述

我遇到了我认为可能是错误的问题,但很可能是我做错了什么。

我的模型中有一个稍微复杂的导航状态变量,用于在 iPad 上进行多任务处理时跟踪/设置选项卡和侧边栏演示之间的状态。除了选项卡模式外,这一切都很好,一旦我使用导航链接,一旦我似乎无法再次使用,无论绑定是在我的选项卡视图还是列表中的导航链接。

在此处输入图像描述

非常感谢对此的任何想法,干杯!

例子

NavigationItem.swift

enum SubNavigationItem: Hashable {
    case overview, user, hobby
}

enum NavigationItem: Hashable {
    case home(SubNavigationItem)
    case settings
}

模型.swift

final class Model: ObservableObject {
    @Published var selectedTab: NavigationItem = .home(.overview)
}

SwiftUIApp.swift

@main
struct SwiftUIApp: App {
    @StateObject var model = Model()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(model)
        }
    }
}

内容视图.swift

struct ContentView: View {
    var body: some View {
        AppTabNavigation()
    }
}

AppTabNavigation.swift

struct AppTabNavigation: View {
    @EnvironmentObject private var model: Model

    var body: some View {
        TabView(selection: $model.selectedTab) {
            NavigationView {
                HomeView()
            }
            .tabItem {
                Label("Home", systemImage: "house")
            }
            .tag(NavigationItem.home(.overview))

            NavigationView {
                Text("Settings View")
            }
            .tabItem {
                Label("Settings", systemImage: "gear")
            }
            .tag(NavigationItem.settings)
        }
    }
}

HomeView.swift

我在这里创建了一个绑定,因为选择需要一个可选的 <NavigationItem?> 不是

struct HomeView: View {
    @EnvironmentObject private var model: Model
    
    var body: some View {
        let binding = Binding<NavigationItem?>(
            get: { 
                model.selectedTab 
            },
            set: {
                guard let item = $0 else { return }
                model.selectedTab = item
            }
        )
        
        List {
            NavigationLink(
                destination: Text("Users"),
                tag: .home(.user),
                selection: binding
            ) {
                Text("Users")
            }
            NavigationLink(
                destination: Text("Hobbies"),
                tag: .home(.hobby),
                selection: binding
            ) {
                Text("Hobbies")
            }
        }
        .navigationTitle("Home")
    }
}

第二次尝试

我尝试selectedTab按照@Lorem Ipsum 的建议将该属性设为可选。这意味着我可以删除那里的绑定。但是 TabView 不适用于该属性。所以我为此创建了一个绑定并且有同样的问题但是标签栏!

在此处输入图像描述

标签: swiftuiswiftui-navigationlinkswiftui-navigationview

解决方案


使选定的选项卡可选

@Published var selectedTab: NavigationItem? = .home(.overview)

并摆脱那个临时绑定变量。只需使用变量

$model.selectedTab

如果变量永远不能为零,那么总是使用该临时变量选择 IAW,它将只保留最后一个值。


推荐阅读