问题描述
在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/