оператор if внутри ForEach в iOS SwiftUI - PullRequest
1 голос
/ 05 августа 2020

У меня есть «если» внутри ForEach в iOS SwiftUI (Xcode версии 11.6), и он работает правильно.

struct ContentView: View {
    var body: some View {
        List {
            ForEach(0 ..< 10) {(i: Int) in
                if i % 2 == 0 {
                    Text(String(i))
                }
            }
        }
    }
}

Теперь я хотел бы сделать то же самое, но с массив строк вместо полуоткрытого диапазона 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)
                }
            }
        }
    }
}

Сообщение об ошибке, которое я получаю из этого ForEach:

Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols

Что пошло не так? Я озадачен, потому что в учебнике Apple по SwiftUI есть «если» внутри ForEach в разделе 3, шаг 1 https://developer.apple.com/tutorials/swiftui/handling-user-input Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 05 августа 2020

Вы можете попробовать следующее:

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)
        }
    }
}

Таким образом, ваш код также может быть более читабельным.

1 голос
/ 06 августа 2020

Возможный метод - использование 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)
                    }
                }
            }
        }
    }
}

Некоторые представления немного более гибки в отношении того, что вы помещаете в них, чем другие. Например, в HStack или VStack вы даже можете разместить несколько (под) представлений, а в ForEach - нет. Группа обладает большой гибкостью, но не влияет на макет, поэтому часто вы можете использовать ее, просто чтобы обернуть в нее сложные представления.

...