代码没有在 ForEach 语句中迭代

Posted

技术标签:

【中文标题】代码没有在 ForEach 语句中迭代【英文标题】:The code is not iterating inside the ForEach statement 【发布时间】:2020-05-02 17:55:26 【问题描述】:

我正在按照底部的要点创建一个标签栏视图。 一切正常,除了当索引更改时 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

【问题讨论】:

【参考方案1】:

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

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

我个人喜欢那里的解释:

working-with-identifiable-items-in-swiftui how-to-create-views-in-a-loop-using-foreach

【讨论】:

以上是关于代码没有在 ForEach 语句中迭代的主要内容,如果未能解决你的问题,请参考以下文章

Swiftui foreach 内部参数

在 C# 中迭代​​字典

foreach 循环的迭代问题

MyBatis 的 foreach 语句

何时使用 forEach(_:) 而不是 for in?

Mybatis 中 foreach 用法