SwiftUI 选项卡选择不适用于任何可散列的内容

SwiftUI Tab Selection Not Working With Any Hashable Content

SwiftUI 的选项卡选择应该适用于任何可散列的内容,但这似乎不起作用。

在提供的示例中,您可以看到在“工作”选项卡中,如果您使用整数作为选项卡选择,则一切正常。当您切换到“Broken”选项卡时,所选内容是 ColorItem,并且所选内容不会更新视图。

我认为这是一个 SwiftUI 错误并已提交反馈 (FB8879981)。

使用 Xcode 12.2 和 iOS 14.2(RC) 进行测试。

struct ColorItem: Identifiable, Hashable{
    let color: Color
    let title: String
    
    var id: String{
        title
    }
}
struct ContentView: View {
    let items = [
        ColorItem(color: .red, title: "Red"),
        ColorItem(color: .blue, title: "Blue"),
        ColorItem(color: .purple, title: "Purple")
    ]
    
    var body: some View {
        TabView{
            TabViewWorking(items: items)
                .tabItem {
                    Label("Working", systemImage: "hand.thumbsup")
                }
            
            TabViewBroken(items: items)
                .tabItem {
                    Label("Broken", systemImage: "hand.thumbsdown")
                }
        }
    }
}
struct TabViewWorking: View {
    @State private var tabSelection = 0
    let items: [ColorItem]
    
    var body: some View {
        ZStack{
            TabView(selection: $tabSelection){
                ForEach(0..<items.count){ i in
                    items[i].color.edgesIgnoringSafeArea(.all)
                        .tag(i)
                }
            }
            .tabViewStyle(PageTabViewStyle())
            
            VStack{
                Text(tabSelection.description)
                Text(items[tabSelection].title)
            }
            .font(.largeTitle)
        }
    }
}
struct TabViewBroken: View {
    @State private var tabSelection = ColorItem(color: .red, title: "Red")
    let items: [ColorItem]

    var body: some View {
        ZStack{
            TabView(selection: $tabSelection){
                ForEach(0..<items.count){ i in
                    items[i].color.edgesIgnoringSafeArea(.all)
                        .tag(i)
                }
            }
            .tabViewStyle(PageTabViewStyle())
            
            VStack{
                Text(items.firstIndex(of: tabSelection)?.description ?? "N/A")
                Text(tabSelection.title)
            }
            .font(.largeTitle)
        }
    }
}

不,这不是 SwiftUI 错误。选择类型和标签类型必须相同,因此在您的第一个场景中它们都是整数,但在第二个场景中它们不相同 - 选择是 ColorItem,但标签仍然是整数 - 因此选择不起作用。

这是固定的变体:

struct TabViewBroken: View {
    @State private var tabSelection = ColorItem(color: .red, title: "Red")
    let items: [ColorItem]

    var body: some View {
        ZStack{
            TabView(selection: $tabSelection){
                ForEach(0..<items.count){ i in
                    items[i].color.edgesIgnoringSafeArea(.all)
                        .tag(items[i])                          // << here !!     
                }
            }
            .tabViewStyle(PageTabViewStyle())
            
            VStack{
                Text(items.firstIndex(of: tabSelection)?.description ?? "N/A")
                Text(tabSelection.title)
            }
            .font(.largeTitle)
        }
    }
}