Проблема в том, что присвоение milesPerGallon
не работает с «синтаксисом компоновщика функций», используемым для построения аргументов иерархии представления. Это становится немного более очевидным, если мы заменим @State var milesPerGallon
на локальную переменную (то есть есть, не содержит состояния, от которого зависит представление, только промежуточное значение):
if showMPGInfo {
Spacer()
let milesPerGallon = CalcMPG(start: startingMileage,
end: endingMileage, fuel: fuelAdded)
Text("Fuel effiency: \(milesPerGallon) MPG")
.font(.largeTitle)
}
Теперь ошибка компилятора
Closure containing a declaration cannot be used with function builder 'ViewBuilder'
Для получения дополнительной информации о синтаксисе компоновщика функций см. Что включает DSL SwiftUI? (который также имеет ссылки на документацию).
Самое простое решение - избежать локальной переменной и напрямую интерполировать текст:
if showMPGInfo {
Spacer()
Text("Fuel effiency: \(CalcMPG(start: startingMileage, end: endingMileage, fuel: fuelAdded)) MPG")
.font(.largeTitle)
}
Другими решениями является вычисление текстового поля в «немедленно оцененном закрытии»:
if showMPGInfo {
Spacer();
{ () -> Text in
let milesPerGallon = CalcMPG(start: startingMileage,
end: endingMileage,
fuel: fuelAdded)
return Text("Fuel effiency: \(milesPerGallon) MPG")
}()
.font(.largeTitle)
}
или для определения вспомогательной функции
func resultField(start: String, end: String, fuel: Double) -> Text {
let milesPerGallon = CalcMPG(start: startingMileage, end: endingMileage, fuel: fuelAdded)
return Text("Fuel effiency: \(milesPerGallon) MPG")
}
и используйте его как
if showMPGInfo {
Spacer()
resultField(start: startingMileage, end: endingMileage,
fuel: fuelAdded)
.font(.largeTitle)
}
Могут быть и другие обходные пути, но это то, что я придумал до сих пор.