首页 > 解决方案 > 代码没有在 ForEach 语句中迭代

问题描述

我正在按照底部的要点创建一个标签栏视图。一切正常,除了当索引更改时 ForEach 语句中的以下内容未执行。所以内容视图不会改变。

ForEach(views.indices) { i in
       self.views[i].view
          .opacity(self.selectedIndex == i ? 1 : 0)
       }

我有其他解决方案来实现我的目标,但我想知道为什么 ForEach 没有按预期工作。任何帮助表示赞赏

import SwiftUI

struct TabView: View {
    var views: [TabBarItem]
    @State var selectedIndex: Int = 0

    init(_ views: [TabBarItem]) {
        self.views = views
    }

    var body: some View {
        ZStack {
            ForEach(views.indices) { i in   // it is not stepping into this when selectedIndex changes!!
                self.views[i].view
                    .opacity(self.selectedIndex == i ? 1 : 0)
            }
            GeometryReader { geometry in
                VStack {
                    Spacer()
                    ZStack(alignment: .top) {
                        LinearGradient(gradient: Gradient(colors: [Color.black.opacity(0.5), Color.black.opacity(0)]), startPoint: .top, endPoint: .bottom)
                            .frame(height: 49 + geometry.safeAreaInsets.bottom)

                        HStack {
                            ForEach(self.views.indices) { i in
                                Button(action: {
                                    self.selectedIndex = i
                                }) {
                                    VStack {
                                        if self.selectedIndex == i {
                                            self.views[i].image
                                                .foregroundColor(.white)
                                                .padding(.top, 8)
                                        } else {
                                            self.views[i].image
                                                .foregroundColor(Color.white.opacity(0.5))
                                                .padding(.top, 8)
                                        }
                                        Text(self.views[i].title)
                                            .foregroundColor(.white)
                                            .font(Font.system(size: 12, weight: .bold))
                                            .opacity(0)
                                    }
                                    .frame(maxWidth: .infinity)
                                }
                            }
                        }
                    }
                }
                .edgesIgnoringSafeArea(.bottom)
                .animation(.easeInOut)
            }
        }
    }
}

struct TabBarItem {
    var view: AnyView
    var image: Image
    var title: String

    init<V: View>(view: V, image: Image, title: String) {
        self.view = AnyView(view)
        self.image = image
        self.title = title
    }
}

struct ContentView: View {
  var body: some View {
    TabView([
      TabBarItem(view: FeedView(),
                 image: Image("house.fill"),
                 title: "Feed"),
      TabBarItem(view: SearchView(),
                 image: Image("loupe"),
                 title: "Explore"),
      TabBarItem(view: CreateView(),
                 image: Image("plus.circle"),
                 title: "Create"),
      TabBarItem(view: LoginView(),
                 image: Image("person.fill"),
                 title: "Profile"),
    ])
  }
}

https://gist.github.com/kishikawakatsumi/562028c46e7549aba658c88366417f6b

标签: iosswiftui

解决方案


SwiftUI 需要知道它如何唯一地识别每个项目,否则它无法比较视图层次结构以找出发生了什么变化,那是因为你id缺少ForEach.

ForEach(views.indices, id: \.self) { i in
   self.views[i].view
       .opacity(self.selectedIndex == i ? 1 : 0)
}

我个人喜欢那里的解释:


推荐阅读