SwiftUI不允许ViewBuilder声明let常量问题
SwiftUI不允许ViewBuilder声明let常量问题

SwiftUI不允许ViewBuilder声明let常量问题

问题描述

在SwiftUI中尝试给图表添加日期,发现下面的代码会引起无法编译的报错。

struct ExchangeRateChart: View {
    var dataPoints: [ExchangeRateChartPoint]
    var body: some View {
        HStack {
            if let first = firstDate,
               let last = lastDate {
                let formatter = DateFormatter()
                formatter.dateFormat = "YYYY-MM-dd"
                Text(formatter.string(from: first))
                Spacer()
                Text(formatter.string(from: middleDate))
                Spacer()
                Text(formatter.string(from: last))
            }
        }
    }
}

报错内容为:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

经过排查发现,当隐藏formatter.dataFormat时,报错消失。

恢复dataFormat代码,则预览报错。

因此,问题定位在DataFormatter部分。

但是这里的DataFormatter代码是没有问题的,因为formatter.dateFormat是DateFormatter的属性,具体请见《Swift UI深入理解DataFormatter》。

经过分析了解到,这里的报错原因为:SwiftUI 不允许在 ViewBuilder 中声明 let 常量(例如 let formatter = …)

简单的来说就是,ViewBuilder内不允许使用let。

HStack {
    if let first = firstDate, let last = lastDate {
        let formatter = DateFormatter()  // ViewBuilder 不允许这里写 let
        ...
    }
}

解决方案

将formatter移到View结构体外:

// 格式化日期
func formattedDate(_ date: Date) -> String {
    let formatter = DateFormatter()
    formatter.dateFormat = "YYYY-MM-dd"
    return formatter.string(from: date)
}

HStack {
    if let first = firstDate,
       let last = lastDate {
        let formatter = DateFormatter()
        Text(formattedDate(first))
        Spacer()
        Text(formattedDate(middleDate))
        Spacer()
        Text(formattedDate(last))
    }
}

问题得到解决。

相关文章

Swift UI深入理解DateFormatter:https://fangjunyu.com/2024/10/06/swift-ui%e6%b7%b1%e5%85%a5%e7%90%86%e8%a7%a3dateformatter/

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注