如何使用 SwiftUI TabView 更多选项卡来阻止它与我选择的选项卡变量混淆

Posted

技术标签:

【中文标题】如何使用 SwiftUI TabView 更多选项卡来阻止它与我选择的选项卡变量混淆【英文标题】:How do I work SwiftUI TabView more tab to stop it mssing with my slected tab variable 【发布时间】:2020-10-06 15:34:07 【问题描述】:

我有一个超过 5 个选项卡的选项卡视图,在 SwiftUI 中它会自动创建一个更多选项卡来显示额外的选项卡。这一直运作良好。 但是,我想设置用户在打开应用程序时看到的第一个选项卡,所以我添加了一个 EnviromentObject 来存储所选选项卡。这允许我设置用户看到的第一个选项卡并以编程方式更改选项卡。例如,在其中一个选项卡上,用户上传了一张需要一段时间才能处理的图像,因此当上传图像时,该功能会更改所选选项卡,然后更改用户视图。

这一切都很好,但是现在更多选项卡不再工作,它尝试显示更多页面,但然后轻弹回到 EnviromentObject 中的选项卡选择。

我怎样才能阻止这种行为?

我的标签视图:


    struct BasicView: View 
        @EnvironmentObject var screenCoordinator: ScreenCoordinator
        @State var climbs:ClimbListData?
        @State var selection = 2
        var body: some View 
            TabView(selection: $screenCoordinator.selection) 
                NavigationView
                    VStack
                        Text("Search")
                    .navigationBarTitle("Climbers Log", displayMode:.inline)
                .tabItem
                    Image(systemName:"magnifyingglass")
                    Text("Search")
                .tag(0)
                NavigationView
                    VStack
                        MapView()
                    .navigationBarTitle("Climbers Log", displayMode:.inline)
                .tabItem
                    Image(systemName: "map.fill")
                    Text("Map")
                .tag(1)
                
                NavigationView
                    VStack
                        ClimbList()
                    .navigationBarTitle("Climbers Log", displayMode:.inline)
    
                .tabItem
                    ScalledImage(name: "climbericon", size: CGSize(width: 24, height: 24))
                    Text("Climbs")
                .tag(2)
                NavigationView
                    VStack
                        AddAClimb()
                    
                .tabItem
                    Image(systemName:"plus")
                    Text("Add Climb")
                .tag(6)
                NavigationView
                    VStack
                        Text("Log")
                    .navigationBarTitle("Climbers Log", displayMode:.inline)
                .tabItem
                    Image(systemName:"book.fill")
                    Text("Log")
                .tag(3)
                NavigationView
                    VStack
                        Text("Profile")
                    .navigationBarTitle("Climbers Log", displayMode:.inline)
                .tabItem
                    Image(systemName:"person.circle")
                    Text("Profile")
                .tag(4)
                NavigationView
                    VStack
                        Text("Settings")
                    .navigationBarTitle("Climbers Log", displayMode:.inline)
                .tabItem
                    Image(systemName:"gear")
                    Text("Settings")
                .tag(5)
                
                NavigationView
                    VStack
                        Text("Stats")
                    .navigationBarTitle("Climbers Log", displayMode:.inline)
                .tabItem
                    ScalledImage(name: "stats", size: CGSize(width: 24, height: 24))
                    Text("Stats")
                .tag(7)
            .edgesIgnoringSafeArea(.top).navigationTitle("").navigationBarHidden(true)
        
        
     

我的环境对象:


    class ScreenCoordinator: ObservableObject 
        @Published var selection = 2 
    

【问题讨论】:

【参考方案1】:

这看起来像是TabView+ObservedObject 的错误。

这是可能的解决方法 - 使用内部状态并将其与环境对象的值同步。使用 Xcode 12 / ios 14 测试。

struct BasicView: View 
        @EnvironmentObject var screenCoordinator: ScreenCoordinator
        @State var climbs:ClimbListData?

        @State private var selection = 0    // << use state !!

        var body: some View 
            TabView(selection: $selection)     // << local selection

               // ... your tabs here
                     
             .edgesIgnoringSafeArea(.top)
             .navigationTitle("").navigationBarHidden(true)
             .onAppear 
                // initially loaded
                self.selection = self.screenCoordinator.selection
            
            .onChange(of: selection) 
                // store local to environment
                self.screenCoordinator.selection = $0
            
            .onReceive(screenCoordinator.$selection) 
                // update state on env changed
                self.selection = $0
            
        

    

【讨论】:

这可以让更多选项卡正常工作,但是当我在函数内更改 EnviromentObject 时,选项卡视图不会改变。

以上是关于如何使用 SwiftUI TabView 更多选项卡来阻止它与我选择的选项卡变量混淆的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:我可以向 TabView 添加更多视图,然后是选项卡项吗?

SwiftUI - 如何将工具栏添加到 NavigationView 内的 TabView 选项卡?

使用tabview更改选项卡时如何使SwiftUI中的计时器保持触发

TabView 在为 SwiftUI 设置动画的选项卡之间切换

SwiftUI:Tabview,更改选项卡时保持状态

SwiftUI 滑动 TabView 时如何访问 ScrollViewReader 的代理