web-dev-qa-db-ja.com

SwiftUI-条件付きクロージャーを使用したif letの代替

私はSwiftUIで以下を実装しようとしています:

struct PersonView: View {

    @State private var age: Int? = 0

    var body: some View {
        VStack {
            Text("Just a test")
            if let self.age > 0 {
                Text("Display Age: \(age)")
            } else {
                Text("Age must be greater than 0!")
            }
        }
    }
}

ただし、SwiftUIでは、if letの結果、次のエラーが発生します。

制御フローステートメントを含むクロージャーは、関数ビルダー 'ViewBuilder'では使用できません

そのため、このトピックを調査した後、.mapを使用してageオプションをアンラップするという推奨事項に出くわしました。したがって、次のようにVStack内のコードに変更しました。

Text("Just a test")
self.age.map {elem in
    if elem > 0 {
        Text("Display Age: \(elem)")
    } else {
        Text("Age must be greater than 0!")
    }
}

ただし、.mapクロージャ内に条件を含めると、VStackを呼び出す行で次のエラーが発生します。

'(ViewBuilder.Type)->(C0、C1)-> TupleView <(C0、C1)>'では、 '()'が 'View'に準拠している必要があります

タイプ「()」はプロトコル「ビュー」に準拠していません

エラーの2番目のセットを回避する方法について何か提案はありますか?または、オプションをアンラップしてSwiftUIで評価する別のアプローチはありますか?本当にSwiftUIに似ていますが、オプションのアンラップが頭痛の種であるとは信じられません!

2
Vee

そのような場合、私は次のアプローチを好みます

struct PersonView: View {

    @State private var age: Int? = 0

    var body: some View {
        VStack {
            Text("Just a test")
            AgeText
        }
    }

    private var AgeText: some View {
        if let age = self.age, age > 0 {
            return Text("Display Age: \(age)")
        } else {
            return Text("Age must be greater than 0!")
        }
    }
}
2
Asperi

Ageの値について2つのチェックを実行しようとしています。最初に、それがnilでないことを確認してから、0より大きいことを確認します。マップを使用して、潜在的なnil次に、3項演算子を使用して、表示されるテキストを条件付きで変更します。

var body: some View {
    VStack {
        Text("Just a test")
        age.map { Text( $0 > 0 ? "Display Age: \($0)" : "Age must be greater than 0!") }
    }
}
3
LuLuGaGa

関数を使用するなど、より基本的なコードにコードをリファクタリングできます。

var body: some View {
    VStack {
        Text("Just a test")
        Text(text(age: age)) // Using the function
    }
}

func text(age: Int?) -> String { // Defining the function
    guard let age = age else { return "Age not found" }
    if age > 0 { return "Display Age: \(age)" }
    else { return "Age must be greater than 0!" }
}

一般に、コードをクリーンアップする必要がある関数を使用します。 Swiftの将来のバージョンが、これを直接サポートしてくれることを期待しています。

2