【问题标题】:SwiftUI - TabView/NavigationLink navigation breaks when using a custom bindingSwiftUI - 使用自定义绑定时 TabView/NavigationLink 导航中断
【发布时间】:2021-07-21 20:45:26
【问题描述】:

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

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

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

示例

NavigationItem.swift

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

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

Model.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)
        }
    }
}

ContentView.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

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

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")
    }
}

第二次尝试

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

【问题讨论】:

    标签: swiftui swiftui-navigationlink swiftui-navigationview


    【解决方案1】:

    使选定的选项卡成为可选的

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

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

    $model.selectedTab
    

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

    【讨论】:

    • 感谢您的回复!我可以这样做,但是 TabView 不起作用,所以我创建了一个类似的绑定,然后我的 TabView 项目有同样的问题。 *我已经用我在这里尝试过的内容更新了帖子
    • 你不能像这样混合两者并期望不同的行为。如果你想让 tabview 工作,你会得到以前的行为,如果你想取消选择链接,你需要这个行为。
    • 如果您有一个按钮或 onChange 激活您的导航链接,您可能会接近
    • 是的,我明白你的建议绝对有效,感谢您的解释。这有点不幸,因为例如使用 TabView 和 Sidebar(navigation links) 。我需要使导航项保持同步,如果我不能使用它,那就不好了。这就是为什么我在需要的地方尝试了一个属性和绑定。很抱歉再问,但您对此有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 2020-11-21
    • 2022-01-21
    • 2020-04-16
    • 2019-06-15
    • 1970-01-01
    • 2021-11-29
    相关资源
    最近更新 更多