Reputation: 99
I have an "if" inside of a ForEach in iOS SwiftUI (Xcode version 11.6) and it works correctly.
struct ContentView: View {
var body: some View {
List {
ForEach(0 ..< 10) {(i: Int) in
if i % 2 == 0 {
Text(String(i))
}
}
}
}
}
Now I would like to do the same thing, but with an array of Strings instead of a half-open range of Ints.
struct ContentView: View {
let states: [String] = [
"Alabama",
"Alaska",
"Arizona",
"Arkansas",
"California"
];
var body: some View {
List {
ForEach(states, id: \.self) {(state: String) in
if state.hasPrefix("Al") {
Text(state)
}
}
}
}
}
The error message I get from this ForEach is
Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols
What has gone wrong? I'm puzzled because Apple's SwiftUI tutorial has an "if" inside of a ForEach in Section 3, Step 1 of
https://developer.apple.com/tutorials/swiftui/handling-user-input
Thank you in advance.
Upvotes: 1
Views: 957
Reputation: 3446
A possible method is using Group
:
struct ContentView: View {
let states: [String] = [
"Alabama",
"Alaska",
"Arizona",
"Arkansas",
"California"
];
var body: some View {
List {
ForEach(states, id: \.self) {(state: String) in
Group {
if state.hasPrefix("Al") {
Text(state)
}
}
}
}
}
}
Some Views are a bit more flexible about what you put inside them than others are. For example, in an HStack or VStack, you can even put multiple (sub)Views, while in ForEach, you can't. Group has a lot of flexibility, but doesn't affect the layout, so often you can use it just to wrap complex views in it.
Upvotes: 1
Reputation: 54611
You may try the following:
struct ContentView: View {
...
var body: some View {
List {
ForEach(states, id: \.self) { state in
self.stateView(state: state)
}
}
}
@ViewBuilder
func stateView(state: String) -> some View {
if state.hasPrefix("Al") {
Text(state)
}
}
}
This way your code may be more readable as well.
Upvotes: 3