私は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に似ていますが、オプションのアンラップが頭痛の種であるとは信じられません!
そのような場合、私は次のアプローチを好みます
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!")
}
}
}
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!") }
}
}
関数を使用するなど、より基本的なコードにコードをリファクタリングできます。
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の将来のバージョンが、これを直接サポートしてくれることを期待しています。