SwiftUI 错误:"包含控制流语句的闭包不能与函数构建器 'ViewBuilder' 一起使用"。

28

我试了一个SwiftUI教程,“处理用户输入”。

https://developer.apple.com/tutorials/swiftui/handling-user-input

我尝试使用for而不是ForEach来实现它。 但是出现了一个错误:"Closure containing control flow statement cannot be used with function builder 'ViewBuilder'".

import SwiftUI

struct LandmarkList: View {
    @State var showFavoritesOnly = true
    
    var body: some View {
        NavigationView{
            List{
                Toggle(isOn: $showFavoritesOnly){
                    Text("Show FavatiteOnly")
                }
                
                ForEach(landmarkData) { landmark in
                    if !self.showFavoritesOnly || landmark.isFavorite {
                            NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
                                LandmarkRow(landmark: landmark)
                            }
                        }
                }
            }
            .navigationBarTitle(Text("Landmarks"))
        }
    }
}

翻译成中文:

import SwiftUI

struct LandmarkList: View {
    @State var showFavoritesOnly = true
    
    var body: some View {
        NavigationView{
            List{
                Toggle(isOn: $showFavoritesOnly){
                    Text("Show FavatiteOnly")
                }
                
                for landmark in landmarkData {
                    if $showFavoritesOnly || landmark.isFavorite {
                        NavigationLink(destination: LandmarkDetail(landmark: landmark)){
                            LandmarkRow(landmark: landmark)}
                        }
                }
            }
            .navigationBarTitle(Text("Landmarks"))
        }
    }
}

4
ForEach 是一个特殊的视图,但 for 是控制流语句,在你尝试放置它的 ViewBuilder 中是不被允许的。 - Asperi
为什么要使用for循环? ForEach视图的存在恰好是因为无法在视图生成器函数中使用常规的for循环。但是你用for循环可以做的任何事情都可以用ForEach完成,所以了解您想要实现什么将有助于我们回答您的问题。 - Jonas Zell
2个回答

17
ForEach符合View,所以从本质上讲,它就像TextField一样是一个View
你不能使用普通的for-in,因为ViewBuilder无法理解什么是命令式的for循环。但ViewBuilder可以理解其他控制流程,比如ifif-elseif let,分别使用buildEither(first:), buildEither(second:), 和 buildif(_:)

6
尝试将if语句注释掉,Xcode可能会向您显示真正的错误。这是一个例子:我之前遇到了这个错误,是因为在我的一个视图中传递给枚举的关联值缺失了。
以下是之前和之后的情况:

之前

Group {
    if let value = valueOrNil {
        FooView(
            bar: [
                .baz(arg1: 0, arg2: 3)
            ]
        )
    }
}

之后

Group {
    if let value = valueOrNil {
        FooView(
            bar: [
                .baz(arg1: 0, arg2: 3, arg3: 6)
            ]
        )
    }
}

1
把这个问题加入到无意义编译器问题的列表中 ¯\(ツ)/¯ 当我刚在一个函数中添加了一个参数时,它真的误导了我。谢谢! - Skwiggs
谢谢,这正是我遇到的同样错误。 - KevinS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接