这是我正在制作的 BMI 计算器的片段。我有两个用户输入英尺和英寸。在此代码中,视图中的步进器应调整英寸,一旦达到 12,则将英尺增加 1 并将英寸重置为 0;反之亦然,一旦达到 0,英尺应减少 1 并重置为 12。
这是我认为应该有效的主要代码块。有趣的是,当我对 if 语句中的逻辑进行微小修改时(下面的两个片段),减少和增加英尺以及重置英寸可以正常工作,但将它们组合起来会使步进器在达到 0 或 12 时处于非活动状态,并且不会调整英尺。
struct NewMetricView: View {
@State private var heightInFeet: Double = 5
@State private var heightInInches: Double = 11
var body: some View {
Stepper("\(heightInFeet, specifier: "%.f") ft \(heightInInches, specifier: "%.1f") in", value: $heightInInches, in: 0...12, step: 0.5)
.onChange(of: heightInInches) { newValue in
if newValue >= 12 {
heightInFeet += 1
heightInInches = 0
} else if newValue <= 0 {
heightInFeet -= 1
heightInInches = 12 + newValue
}
// Recalculate BMI when height stepper changes
}
}
}
有趣的是,这段代码允许步进器正确调整:
Stepper("\(heightInFeet, specifier: "%.f") ft \(heightInInches, specifier: "%.1f") in", value: $heightInInches, in: 0...12, step: 0.5)
.frame(width: 250)
.font(.title)
.padding(.bottom, 5)
.onChange(of: heightInInches) { newValue in
if newValue >= 12 {
heightInFeet += 1
heightInInches = 0
} else if newValue < 0 {
heightInFeet -= 1
heightInInches = 12 + newValue
}
// Recalculate BMI when height stepper changes
}
这段代码可以正确调整事情
Stepper("\(heightInFeet, specifier: "%.f") ft \(heightInInches, specifier: "%.1f") in", value: $heightInInches, in: 0...12, step: 0.5)
.frame(width: 250)
.font(.title)
.padding(.bottom, 5)
.onChange(of: heightInInches) { newValue in
if newValue > 12 {
heightInFeet += 1
heightInInches = 0
} else if newValue <= 0 {
heightInFeet -= 1
heightInInches = 12 + newValue
}
// Recalculate BMI when height stepper changes
}
我真的不知道为什么两者结合起来不起作用。
您的问题是,当
heightInInches
更改时,您正在修改 heightInInches
,这会导致 .onChange()
再次触发,而 SwiftUI 不喜欢这样。
解决此问题的最简单方法是使用单个
@State var
来表示您的身高(以英寸为单位)。然后您可以提取英尺和英寸进行显示。在这里,我使用计算变量 heightInFeet
和 heightInInches
来计算 totalHeight
中的值:
struct NewMetricView: View {
@State private var totalHeight: Double = 5 * 12 + 11 // Initial value 5 ft 11 in
var heightInFeet: Int { Int(totalHeight) / 12 }
var heightInInches: Double { totalHeight.truncatingRemainder(dividingBy: 12) }
var body: some View {
Stepper("\(heightInFeet) ft \(heightInInches, specifier: "%.1f") in", value: $totalHeight, in: 12...108, step: 0.5)
.onChange(of: totalHeight) { newValue in
// Recalculate BMI when height stepper changes
}
}
}