Swift中修改后的变量值无法正确传递的问题求助
解决Activity Level变量在计算函数中始终为0.0的问题
看起来你遇到的问题是:点击活动级别按钮时明明已经修改了activitylevel的值,但在CaloriesCalculator方法里调用时它还是初始的0.0。你不想用UserDefaults是完全正确的——这只是控制器内部的临时状态,根本不需要持久化存储。
我来帮你分析一下可能的原因,以及给出更可靠的解决方案:
最可能的问题根源
你当前的代码是通过对比按钮的图片来判断哪个按钮被选中,但这种方式有两个大坑:
- IBOutlet未正确连接:如果
LightlyActive、Active、VeryActive这三个按钮的IBOutlet没有在Storyboard里和代码中的变量绑定,那你的判断条件永远不会成立,activitylevel自然一直是0.0。 - 图片对比不可靠:即使是同一张图片,
pngData()的结果可能因为加载方式、缓存等原因出现细微差异,导致对比失败。
推荐解决方案:用Tag或直接判断Sender
放弃图片对比的方式,改用更直观可靠的按钮标识方法,这里推荐用Tag:
步骤1:给按钮设置Tag
打开Storyboard,选中你的三个活动级别按钮,分别在属性面板里设置Tag:
- LightlyActive → Tag = 1
- Active → Tag = 2
- VeryActive → Tag = 3
步骤2:修改按钮点击方法
把ActivityLevelButton方法改成下面这样,既可以正确设置activitylevel,还能直观显示哪个按钮被选中:
@IBAction func ActivityLevelButton(_ sender: UIButton) { // 先重置所有按钮的默认图片,确保只有选中的按钮是绿色状态 LightlyActive.setImage(UIImage(named: "LightlyActive"), for: .normal) Active.setImage(UIImage(named: "Active"), for: .normal) VeryActive.setImage(UIImage(named: "VeryActive"), for: .normal) // 根据按钮Tag设置对应的活动系数,并切换选中按钮的图片 switch sender.tag { case 1: activitylevel = 1.375 sender.setImage(UIImage(named: "LightlyActiveGreen"), for: .normal) case 2: activitylevel = 1.55 sender.setImage(UIImage(named: "ActiveGreen"), for: .normal) case 3: activitylevel = 1.755 sender.setImage(UIImage(named: "VeryActiveGreen"), for: .normal) default: // 处理意外情况,设置默认系数 activitylevel = 1.0 } print("当前活动系数:\(activitylevel)") }
额外优化:给计算方法添加输入验证
你的CaloriesCalculator里用了强制解包!,如果用户输入无效内容会直接崩溃,建议改成安全的可选绑定:
@IBAction func CaloriesCalculator(_ sender: UIButton) { // 验证体重输入 guard let weightText = Weight.text, let weight = Double(weightText), weight > 0 else { print("请输入有效的体重数值") return } // 验证身高输入并转换单位 guard let heightText = Height.text, let heightCm = Double(heightText), heightCm > 0 else { print("请输入有效的身高数值") return } let heightInch = heightCm * 0.393701 // 验证年龄输入 guard let ageText = Age.text, let age = Double(ageText), age > 0 else { print("请输入有效的年龄数值") return } // 计算BMR和目标卡路里 let bmr = 66 + (6.23 * weight) + (12.7 * heightInch) - (6.8 * age) let tde = activitylevel * bmr calGoal = tde print("活动系数:\(activitylevel),目标卡路里:\(calGoal)") }
最后检查
一定要确认LightlyActive、Active、VeryActive这三个按钮的IBOutlet已经正确连接——在Storyboard里按住Ctrl拖动按钮到代码中对应的变量上,确保连接成功。
这样修改后,activitylevel的值就会正确传递到计算方法里了。
内容的提问来源于stack exchange,提问作者AnonAnon
相关产品推荐
相关产品推荐

