【问题标题】:SwiftUI TabView: Set selected tabItem from different view but detecting repeated selectionSwiftUI TabView:从不同的视图设置选定的tabItem,但检测到重复选择
【发布时间】:2020-12-23 08:40:26
【问题描述】:

我想显示一个TabView 来显示不同的屏幕。我的第一个屏幕(主页)显示三个按钮,可以选择三个屏幕中的一个来显示。 但是(!)我必须检查是否重复选择了一个选项卡以在这种情况下触发特殊操作。

检测 screen2 的重复选择工作正常,但我无法通过按钮设置选择。 我尝试使用@EnvironmentalObject,但在我的 TabView.selection 中未观察到对此对象的更改。

   import SwiftUI

   @main
   struct TestApp: App {
       static let kIndex0 = 0
       static let kIndex1 = 1
       static let kIndex2 = 2

       var appState = AppState()

       @State private var selection = TestApp.kIndex0

       var body: some Scene {
           // this code is required to detect a repeated selection of
           // the same tab to trigger a special action
           let index = Binding<Int>(
               get: { self.selection },
               set: {
                   if $0 == TestApp.kIndex1  &&  self.selection == $0 {
                       print("Trigger special action for index 1")
                   }
                   print("Pressed tab: \($0)  self.selction: \(self.selection)  app.selectedTab: \(appState.selectedTab)")

                   self.selection = $0
                   appState.selectedTab = $0
               })

           WindowGroup {
               TabView(selection: index) {
                   First()
                       .environmentObject(appState)
                      .tabItem {
                           Image(systemName: "1.circle")
                           Text("Home")
                       }.tag(TestApp.kIndex0)
                
                   Text("Second Content View")
                       .tabItem {
                           Image(systemName: "2.circle")
                           Text("Screen Two")
                       }.tag(TestApp.kIndex1)

                   Text("Third Content View")
                       .tabItem {
                           Image(systemName: "3.circle")
                           Text("Screen Three")
                       }.tag(TestApp.kIndex2)
               }
           }
       }
   }


   class AppState: ObservableObject {
       @Published var selectedTab = TestApp.kIndex0
   }


   /*
       Place to buttons which should select on of the the two
       tabs of TestUI
    */
   struct First: View {
       @EnvironmentObject var appState: AppState

       var body: some View {
           VStack(alignment: .leading, spacing: 20) {
               AButton(tabIndex: TestApp.kIndex0, iconName: "1.circle", text: "This first screen")
                   .environmentObject(appState)

               AButton(tabIndex: TestApp.kIndex1, iconName: "2.circle", text: "Second screen")
                   .environmentObject(appState)

                  AButton(tabIndex: TestApp.kIndex1, iconName: "3.circle", text: "Third screen")
                   .environmentObject(appState)
           }
       }
   }


   struct AButton: View {
       let tabIndex: Int
       let iconName: String
       let text: String

       @EnvironmentObject var appState: AppState

       var body: some View {
           Button(action: {
               appState.selectedTab = tabIndex
           }) {
               HStack() {
                   Image(systemName: iconName)
                       .imageScale(.large)
                       .frame(minWidth: 50)
                   Text(text)
               }
           }
       }
   }

【问题讨论】:

    标签: button swiftui controls tabview


    【解决方案1】:

    你需要让appState被观察,你根本不需要selection(它只是一个重复)。

    我已经把所有东西都放在了单独的ContentView 中(只为场景离开场景)

    使用 Xcode 12 / iOS 14 测试

    struct ContentView: View {
    
        @StateObject var appState = AppState()
    
        var body: some View {
            // this code is required to detect a repeated selection of
            // the same tab to trigger a special action
            let index = Binding<Int>(
                get: { self.appState.selectedTab },
                set: {
                    if $0 == TestApp.kIndex1  &&  self.appState.selectedTab == $0 {
                        print("Trigger special action for index 1")
                    }
                    print("Pressed tab: \($0) app.selectedTab: \(appState.selectedTab)")
                    appState.selectedTab = $0
                })
    
            TabView(selection: index) {
                First()
                    .environmentObject(appState)
                    .tabItem {
                        Image(systemName: "1.circle")
                        Text("Home")
                    }.tag(TestApp.kIndex0)
    
                Text("Second Content View")
                    .tabItem {
                        Image(systemName: "2.circle")
                        Text("Screen Two")
                    }.tag(TestApp.kIndex1)
    
                Text("Third Content View")
                    .tabItem {
                        Image(systemName: "3.circle")
                        Text("Screen Three")
                    }.tag(TestApp.kIndex2)
            }
        }
    }
    
    
    class AppState: ObservableObject {
        @Published var selectedTab = TestApp.kIndex0
    }
    
    
    struct First: View {
        @EnvironmentObject var appState: AppState
    
        var body: some View {
            VStack(alignment: .leading, spacing: 20) {
                AButton(tabIndex: TestApp.kIndex0, iconName: "1.circle", text: "This first screen")
    
                AButton(tabIndex: TestApp.kIndex1, iconName: "2.circle", text: "Second screen")
    
                AButton(tabIndex: TestApp.kIndex2, iconName: "3.circle", text: "Third screen")
            }
        }
    }
    
    
    struct AButton: View {
        let tabIndex: Int
        let iconName: String
        let text: String
    
        @EnvironmentObject var appState: AppState
    
        var body: some View {
            Button(action: {
                appState.selectedTab = tabIndex
            }) {
                HStack() {
                    Image(systemName: iconName)
                        .imageScale(.large)
                        .frame(minWidth: 50)
                    Text(text)
                }
            }
        }
    }
    

    【讨论】:

    • 谢谢,也可以在我的 XCode(12 beta 6,iOS14)中使用。我以为我尝试了类似的解决方案,但现在我不确定。感谢您的帮助。
    猜你喜欢
    • 2020-04-20
    • 1970-01-01
    • 2020-11-14
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多