I tried a SwiftUI tutorial, "Handling User Input".
https://developer.apple.com/tutorials/swiftui/handling-user-input
I tried implementing it with for
instead of ForEach
.
But an error arose: "Closure containing control flow statement cannot be used with function builder 'ViewBuilder'".
FROM:
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"))
}
}
}
TO (I wrote):
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"))
}
}
}
The ForEach
confirms to View
, so at its core, it is a View
just like a TextField
. ForEach Relationships
You can't use a normal for-in
because the ViewBuilder
doesn't understand what is an imperative for-loop. The ViewBuilder
can understand other control flow like if
, if-else
or if let
using buildEither(first:), buildEither(second:), and buildif(_:) respectively.
I was getting this error because of a missing associated value of an enum passed to one of my views.
Here's how it looked like before and after:
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)
]
)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With