在使用ForEach的SwiftUI中选择时,是否可以更改tabItem的图像?

时间:2020-09-02 15:19:15

标签: foreach swiftui tabview

考虑SwiftUI中最简单的选项卡视图应用程序:

struct ContentView: View {
    @State private var selection = 0
 
    var body: some View {
        TabView(selection: $selection){
            Text("First View")
                .font(.title)
                .tabItem {
                    VStack {
                        Image("first")
                        Text("First")
                    }
                }
                .tag(0)
            Text("Second View")
                .font(.title)
                .tabItem {
                    VStack {
                        Image("second")
                        Text("Second")
                    }
                }
                .tag(1)
        }
    }
}

每当点击选项卡时,都会重新加载选项卡项目,并且如果需要,可以通过将选择内容与标签进行比较来更改所选选项卡的图像。但是,如果变量中的标签数量是动态的,并且使用ForEach来显示它们,则该方法将无效:

struct ContentView: View {
    @State private var selection = 0

    private var items: [AnyView] {
        return [
            AnyView(Text("First View")
                .font(.title)
                .tabItem {
                        VStack {
                            Image("first1")
                            Text("First1")
                        }
                }
                .tag(0)),
            AnyView(Text("Second View")
                .font(.title)
                .tabItem {
                    VStack {
                        Image("second")
                        Text("Second")
                    }
                }
                .tag(1))
        ]
    }
 
    var body: some View {
        TabView(selection: $selection){
            ForEach(0..<self.items.count) { index in
                self.items[index]
            }
        }
    }
}

重新加载视图时,不会调用ForEach的正文。是否可以在TabView中使用ForEach的同时完成图像更改?

2 个答案:

答案 0 :(得分:1)

尝试以下操作:

struct ContentView: View {
    @State private var selection = 0
 
    var body: some View {
        TabView(selection: $selection){
            Text("First View")
                .font(.title)
                .tabItem {
                    VStack {
                        Image(systemName: selection == 0 ? "xmark" : "plus")
                        Text("First")
                    }
                }
                .tag(0)
            Text("Second View")
                .font(.title)
                .tabItem {
                    VStack {
                        Image(systemName: selection == 1 ? "xmark" : "minus")
                        Text("Second")
                    }
                }
                .tag(1)
        }
    }
}

答案 1 :(得分:0)

答案在文档中!在范围内使用ForEach时:

    /// Creates an instance that computes views on demand over a *constant*
    /// range.
    ///
    /// This instance only reads the initial value of `data` and so it does not
    /// need to identify views across updates.
    ///
    /// To compute views on demand over a dynamic range use
    /// `ForEach(_:id:content:)`.

因此,请使用ForEach(_:id:content:)