在 SwiftUI 中使用状态变量作为函数的输入
Posted
技术标签:
【中文标题】在 SwiftUI 中使用状态变量作为函数的输入【英文标题】:Using state variables as inputs to a func in SwiftUI 【发布时间】:2019-06-16 05:35:50 【问题描述】:我有两个文本字段可以更改两个@State 变量的值,即startingMileage 和endingMileage,还有一个步进器可以更改名为fuelAdded 的第三个@State 变量的值。我正在尝试使用用户的输入并进行计算以计算每加仑英里数。在操场上,我的代码按预期工作。但是,它不适用于 SwiftUI 项目。
尝试在操场上运行代码如下:
func CalcMPG(start: String, end: String, fuel: Double) -> Int
let start = Int(start) ?? 1
let end = Int(end) ?? 1
let fuel = Int(fuel)
let mpg = (end-start) / fuel
return mpg
var endingMileage:String = "9250"
var startingMileage:String = "9000"
var fuelAdded:Double = 20
let milesPerGallon = CalcMPG(start: startingMileage, end: endingMileage, fuel: fuelAdded)
print("Fuel Efficiency: \(milesPerGallon) mpg")
这按预期工作。
struct ContentView : View
@State var startingMileage: String = ""
@State var endingMileage: String = ""
@State var fuelAdded: Double = 10
@State var carModel: String = ""
@State var showMPGInfo = false
@State var milesPerGallon: Int = 10
func CalcMPG(start: String, end: String, fuel: Double) -> Int
let start = Int(start) ?? 1
let end = Int(end) ?? 1
let fuel = Int(fuel)
let mpg = (end-start) / fuel
return mpg
var body: some View
NavigationView
VStack
HStack
Text("Car Model:")
Spacer()
TextField($carModel, placeholder: Text("Toyota Corolla"))
.textFieldStyle(.roundedBorder)
HStack
Text("Starting ODO:")
Spacer()
TextField($startingMileage, placeholder: Text("8000"))
.textFieldStyle(.roundedBorder)
Text("miles")
HStack
Text("Ending ODO:")
Spacer()
TextField($endingMileage, placeholder: Text("9000"))
.textFieldStyle(.roundedBorder)
Text("miles")
HStack
Stepper(value: $fuelAdded, in: 0...20, step: 0.5)
Text("Fuel Added: \(fuelAdded, specifier: "%0.1f") gallons")
Button(action:
self.showMPGInfo.toggle() )
Text("Show/Hide MPG")
if showMPGInfo
Spacer()
milesPerGallon = CalcMPG(start: startingMileage, end: endingMileage, fuel: fuelAdded)
Text("Fuel effiency: \(milesPerGallon) MPG")
.font(.largeTitle)
.padding()
.navigationBarTitle(Text("Gas Mileage Calculator"))
当用户点击“显示/隐藏 MPG”时。我希望最终生成的文本是“燃料效率:xx MPG”
但是,我收到以下错误:
ContentView.swift:34:19:无法推断复杂的闭包返回类型;添加显式类型以消除歧义
它对我来说没有任何意义...它突出显示 NavigationView 中的起始 VStack。
有什么想法吗?
【问题讨论】:
好的,这一定与milesPerGallon = CalcMPG(...)
的声明有关,因为只要我把它拿出来并把 (CalcMPG(...)) 放入我想要返回的文本中它可以按需要工作。有人知道我在这里做错了什么吗?在这种情况下使用 @State 变量是不是不对?
【参考方案1】:
问题在于milesPerGallon
的赋值不能很好地与用于构建视图层次结构参数的“函数构建器语法”一起使用。如果我们将@State var milesPerGallon
替换为局部变量(即is,它不携带视图所依赖的状态,只有一个中间值),就会变得更加明显:
if showMPGInfo
Spacer()
let milesPerGallon = CalcMPG(start: startingMileage,
end: endingMileage, fuel: fuelAdded)
Text("Fuel effiency: \(milesPerGallon) MPG")
.font(.largeTitle)
现在编译错误是
包含声明的闭包不能与函数生成器“ViewBuilder”一起使用有关函数构建器语法的更多信息,请参阅What enables SwiftUI's DSL?(其中还包含指向文档的链接)。
最简单的解决方案是避免使用局部变量并直接插入文本:
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)
可能还有其他解决方法,但这是我目前想到的。
【讨论】:
以上是关于在 SwiftUI 中使用状态变量作为函数的输入的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI Picker 在同一视图中更改第二个状态变量