SwiftUI中如何合并Int与String数组实现配对展示及数值计算
SwiftUI 配对展示两个数组元素+动态倍数计算实现方案
现有代码问题
- 食材名称、数量拆分为两个独立数组,若两个数组长度不一致会触发下标越界崩溃
Zutaten子视图未接收父视图的Portionen(份数)参数,无法实现数量随份数动态更新- 子视图中父视图传入的参数错误使用
@State声明,@State仅用于视图内部私有状态,外部传入参数用let声明即可避免状态同步异常 - 遍历逻辑仅覆盖食材名称数组,未关联对应数量;外层用
HStack会把所有内容挤在同一行,无法实现逐行展示效果 - 图片修饰符
.frame(width: .infinity)为无效语法,宽度撑满需要用maxWidth: .infinity
可直接运行的修正代码(兼容原有双数组传参写法)
struct Recipe: View { @State var Eiweiß: Int = 23 @State var Kohlenhydrate: Int = 24 @State var Fett: Int = 13 @State var Calories: Int = 423 @State var Portionen: Int = 1 var body: some View { ScrollView{ Image("Burger") .resizable() .frame(maxWidth: .infinity, maxHeight: 250) .padding(.bottom, 10) VStack(spacing: 20) { PortionenAngabe(Portionen: $Portionen) Werte(Eiweiß: $Eiweiß, Kohlenhydrate: $Kohlenhydrate, Fett: $Fett, Calories: $Calories, Portionen: $Portionen) // 传入当前份数给食材列表视图 Zutaten( zutaten: ["Hack", "Mehl", "Brokkoli"], menge: [100, 200, 300], portionen: Portionen ) } } .ignoresSafeArea(.all) } } struct Zutaten: View{ let zutaten: [String] let menge: [Int] let portionen: Int // 安全校验:取两个数组的最小长度,避免越界崩溃 private var validItemCount: Int { min(zutaten.count, menge.count) } var body: some View{ VStack(alignment: .leading, spacing: 8) { // 按下标遍历,配对同位置的数量和食材名 ForEach(0..<validItemCount, id: \.self) { index in let displayMenge = menge[index] * portionen Text("\(displayMenge) \(zutaten[index])") } } .frame(maxWidth: .infinity, alignment: .leading) .multilineTextAlignment(.leading) .navigationBarHidden(true) } }
推荐优化写法(避免数组越界风险)
如果后续需要扩展食材的单位、备注等属性,建议定义统一模型封装单条食材的所有属性,从根源上避免两个数组长度不匹配的问题:
// 定义食材模型,遵循Identifiable方便遍历 struct Zutat: Identifiable { let id = UUID() let name: String let baseQuantity: Int } // 父视图中修改传参方式 Zutaten( zutaten: [ Zutat(name: "Hack", baseQuantity: 100), Zutat(name: "Mehl", baseQuantity: 200), Zutat(name: "Brokkoli", baseQuantity: 300) ], portionen: Portionen ) // 对应修改Zutaten视图 struct Zutaten: View{ let zutaten: [Zutat] let portionen: Int var body: some View{ VStack(alignment: .leading, spacing: 8) { ForEach(zutaten) { item in Text("\(item.baseQuantity * portionen) \(item.name)") } } .frame(maxWidth: .infinity, alignment: .leading) .multilineTextAlignment(.leading) .navigationBarHidden(true) } }
内容的提问来源于stack exchange,提问作者Marius Jensch
相关产品推荐
相关产品推荐

