如何使用 SwiftUI 使这个 ForEach 函数工作?

Posted

技术标签:

【中文标题】如何使用 SwiftUI 使这个 ForEach 函数工作?【英文标题】:How do I make this ForEach function work using SwiftUI? 【发布时间】: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 的工作原理非常重要。 【参考方案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"))

        

    


【讨论】:

以上是关于如何使用 SwiftUI 使这个 ForEach 函数工作?的主要内容,如果未能解决你的问题,请参考以下文章

如果它不可见,SwiftUI 如何使 NavigationLink 工作?

在 SwiftUI 中,如何在 LinkedList 中“Foreach”节点?

SwiftUI ForEach 刷新使视图弹出

SwiftUI:VStack 中 ForEach 中的 HStack 使多行文本重叠

如何使 SwiftUI 滚动视图缩小到内容?

如何在 SwiftUI ForEach 内容中将多个按钮操作分开?