【问题标题】:How do I make this ForEach function work using SwiftUI?如何使用 SwiftUI 使这个 ForEach 函数工作?
【发布时间】:2019-09-04 15:30:46
【问题描述】:

我正在努力学习这个聊天应用教程,并且在 SwiftUI 中更新了 ForEach 函数的语法。你能帮我用 SwiftUI 成功编译这个列表吗?

import SwiftUI

struct ChatMessage : Hashable {
    var message: String
    var avatar: String
}

struct ContentView : View {
    var messages = [
        ChatMessage(message: "Hello world", avatar: "A"),
        ChatMessage(message: "Hi", avatar: "B")
    ]

    var body: some View {
        List {
            ForEach(messages.identified(by: \.self)) {
                Text($0.avatar)
                Text($0.message)
            }
        }
    }
}

我尝试将 ForEach 更改为更新后的语法:

var body: some View {
        List {
            ForEach(messages, id: \.self) {
                Text($0.avatar)
                Text($0.message)
            }
        }
    }

但是,我收到一条错误消息: “无法推断复杂的闭包返回类型;添加显式类型以消除歧义”

【问题讨论】:

  • HStackVStack 中嵌入两个Text 视图。基本上,您的ForEach 就像创建一个表格单元格。在基本视图中,您不能只放置两个 Text 子视图而没有某种堆栈 - 您也不能在 ForEach 中。
  • 我知道我很烦人,但正如我在回答中所说,你的问题有一个很大的错误:ForEach 不是一个函数,它是一个实现 View 协议的结构。这对于理解 SwiftUI 的工作原理非常重要。

标签: list foreach swiftui hashable


【解决方案1】:

@dfd 已经在上面的评论中回答了你。这里的问题与ForEach 视图无关(请注意这个重要的事情:ForEach 不是函数,是View,它与forEach 完全不同你习惯于在 Swift 中)。

ForEach 视图一个接一个地获取数组中的元素,并为每个元素构建一个视图。在您的 @ViewBuilder 闭包(紧跟在ForEach 之后的闭包)中,您传递的视图不止一个。您必须根据需要将两个 Text 包装在一个视图中。例如,如果您希望文本垂直堆叠,您必须这样做:

struct ChatMessage : Hashable {
    var message: String
    var avatar: String
}

struct ContentView : View {
    var messages = [
        ChatMessage(message: "Hello world", avatar: "A"),
        ChatMessage(message: "Hi", avatar: "B")
    ]

    var body: some View {
        List {
            ForEach(messages, id: \.self) {val in
                VStack {
                    Text(val.avatar)
                    Text(val.message)
                }
            }
        }
    }
}

【讨论】:

    【解决方案2】:
    struct ContentView: View {
    
        @State var showFavoritesOnly = true
    
        var body: some View {
    
            NavigationView {
    
                List {
    
                    ForEach(landmarkData) { landmark in
    
                        if !self.showFavoritesOnly || landmark.isFavorite {
    
                            NavigationLink(destination: UserDetail(landmark: landmark)) {
    
                                UsersList(landmark: landmark)
    
                            }
    
                        }
    
                    }
    
                }
    
                .navigationBarTitle(Text("Users"))
    
            }
    
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-26
      • 1970-01-01
      • 2020-02-09
      • 2020-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      相关资源
      最近更新 更多