View SwiftUI-使用条件闭包替代if-let

View SwiftUI-使用条件闭包替代if-let,view,closures,conditional-statements,swiftui,optional,View,Closures,Conditional Statements,Swiftui,Optional,我试图在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)")

我试图在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
打开
年龄
选项。因此,我修改了
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”要求“()”符合“视图”

类型“()”不符合协议“视图”

关于如何克服第二组错误,有什么建议吗?或者,是否有其他方法可以在SwiftUI中展开选项并对其进行评估?真的很喜欢SwiftUI,但不敢相信拆开眼镜会让人头疼

Swift 5.3(代码12) 现在,您可以在视图生成器中使用条件绑定权限:

if let age = age {
    if age > 0 {
        Text("Display Age: \(age)")
    } else {
        Text("Age must be greater than 0!")
    }
} else {
    Text("Age not found")
}

重构(也适用于较旧的雨燕) 您可以将代码重构为更基本的功能,如使用函数:

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的未来版本能像我们预期的那样直接支持这一点。

对于这种情况,我更喜欢以下方法

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

您尝试对年龄值执行两项检查:首先确保它不是
nil
,然后检查它是否大于0。 您可以使用map去除潜在的
nil
,然后使用三元运算符有条件地更改显示的文本:

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

谢谢,@LuLuGaGa!使用三元运算符帮助我解决了这个问题。我最终接受了Asperi的解决方案,因为这是一种更为通用的方法,可以更好地组织代码,并且克服了SwiftUI对noet支持
if let
(如果let)的不足。感谢@Mojtaba的重构。除了克服不支持
if-let
guard-let
的SwiftUI缺点之外,组织起来肯定更好。最后,我接受了Asperi的解决方案,因为它也重构了
视图
对象。请注意,如果要尝试在
if let
条件失败时提供
EmptyView()
,则此方法不起作用。因此,正如@lulugaai所建议的那样,使用.map可能更可取。我很好奇,为什么最初的版本不起作用,这实际上是如何解决问题的?似乎()涵盖了一些主题,但它相当复杂。