[英]Bind to a struct property in a SwiftUI Mac app
我正在 SwiftUI 中構建一個 macOS 單位轉換器應用程序。 在下面的示例中,我有一個包含許多文本字段的加速視圖。 這些文本字段代表不同的加速度單位。
// AccelerationView.swift
struct AccelerationView: View {
@State private var accel = Acceleration()
@EnvironmentObject var formatter: Formatter
var body: some View {
VStack(alignment: .leading) {
Text("Metric").font(.subheadline)
HStack {
TextField("kilometer per second squared", value: $accel.kilometerPerSecondSquare, formatter: formatter.numberFormatter).frame(width: 120)
Text("km/s²").frame(width: 60, alignment: .leading)
}
HStack {
TextField("meter per second squared", value: $accel.meterPerSecondSquare, formatter: formatter.numberFormatter).frame(width: 120)
Text("m/s²").frame(width: 60, alignment: .leading)
}
HStack {
TextField("millimeter per second squared", value: $accel.millimeterPerSecondSquare, formatter: formatter.numberFormatter).frame(width: 120)
Text("mm/s²").frame(width: 60, alignment: .leading)
}
// and so on ...
}
.padding()
}
}
我想將 HStack 放入自己的文件中以清理視圖中的代碼。 我在這方面的嘗試如下所示:
// UnitTextField.swift
struct UnitTextField: View {
@State var value: Double = 0.0
let placeHolder: String
let label: String
var fieldWidth: CGFloat = 120
var labelWidth: CGFloat = 60
@EnvironmentObject private var formatter: Formatter
var body: some View {
HStack {
TextField(placeHolder, value: $value, formatter: formatter.numberFormatter)
.frame(width: fieldWidth)
.multilineTextAlignment(.trailing)
Text(label)
.frame(width: labelWidth, alignment: .leading)
}
}
}
這不起作用,因為 UnitTextField value
沒有正確綁定到加速結構。 我正在嘗試完成這樣的事情,我可以在 AccelerationView 中使用:
// AccelerationView.swift
struct AccelerationView: View {
@State private var accel = Acceleration()
@EnvironmentObject var formatter: Formatter
var body: some View {
VStack(alignment: .leading) {
Text("Metric").font(.subheadline)
UnitTextField(value: $accel.kilometerPerSecondSquare, placeHolder: "kilometer per second squared", label: "km/s²")
UnitTextField(value: $accel.meterPerSecondSquare, placeHolder: "meter per second squared", label: "m/s²")
UnitTextField(value: $accel.millimeterPerSecondSquare, placeHolder: "millimeter per second squared", label: "mm/s²")
// and so on ...
}
.padding()
}
}
關於如何在 SwiftUI 中為 macOS 應用程序正確實現這一點的任何建議?
如果從你要完成的事情(最后一個快照)開始,那么我認為你需要
struct UnitTextField: View {
@Binding var value: Double
代替
struct UnitTextField: View {
@State var value: Double = 0.0
binding
和environmentObject
可能是這樣的:
class MyFormat: Formatter, ObservableObject{
var numberFormat = NumberFormatter()
}
struct UnitTextField: View {
@Binding var value: Double
let placeHolder: String
let label: String
var fieldWidth: CGFloat = 120
var labelWidth: CGFloat = 60
@EnvironmentObject var formatter: MyFormat
var body: some View {
HStack {
TextField(placeHolder, value: $value, formatter: formatter.numberFormat)
.frame(width: fieldWidth)
.multilineTextAlignment(.trailing)
Text(label)
.frame(width: labelWidth, alignment: .leading)
}
}
}
struct Acceleration{
var kilometerPerSecondSquare : Double = 0.0
var meterPerSecondSquare : Double = 1.0
var millimeterPerSecondSquare : Double = 2.0
}
struct AccelerationView: View {
@State private var accel = Acceleration()
@EnvironmentObject var formatter: MyFormat
var body: some View {
VStack(alignment: .leading) {
Text("Metric").font(.subheadline)
UnitTextField(value: $accel.kilometerPerSecondSquare, placeHolder: "kilometer per second squared", label: "km/s²").environmentObject(formatter)
UnitTextField(value: $accel.meterPerSecondSquare, placeHolder: "meter per second squared", label: "m/s²").environmentObject(formatter)
UnitTextField(value: $accel.millimeterPerSecondSquare, placeHolder: "millimeter per second squared", label: "mm/s²").environmentObject(formatter)
// and so on ...
}
.padding()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.