Swift使用协议代理按触发按钮更新对应视图控制器卡路里标签的问题
实现思路
- 新增餐段枚举类型,用来区分当前要更新的是早餐/午餐/晚餐的卡路里数据
- 修改原有代理协议,增加餐段类型参数,回调时可以明确更新对应位置的标签
- 给SearchViewController新增餐段存储属性,接收LogViewController跳转时传递的餐段标识
- 点击不同餐段的添加按钮时,传递对应餐段作为参数触发跳转
- 代理回调时根据餐段类型,判断更新对应UILabel的内容
修正后完整代码
首先修正原代码存在的两个问题:1. delegate拼写错误(原代码写为delagate);2. LogViewController不应该嵌套在SearchViewController内部
import UIKit // 新增餐段枚举 enum MealType { case breakfast, lunch, dinner } // 修改代理协议,增加餐段参数,加AnyObject避免循环引用 protocol DataDelegate: AnyObject { func updateLogCalories(mealType: MealType, calStr: String?) } class SearchViewController: UIViewController, UITextFieldDelegate, CalorieManagerDelegate { // 修正拼写错误,加weak避免循环引用 weak var delegate: DataDelegate? // 新增属性,存储当前跳转对应的餐段 var currentMealType: MealType! @IBOutlet weak var searchTF: UITextField! @IBOutlet weak var calorieLabel: UILabel! @IBOutlet weak var foodNameLabel: UILabel! var calorieManager = CalorieManager() var logCals : String? override func viewDidLoad() { super.viewDidLoad() calorieManager.delegate = self searchTF.delegate = self } @IBAction func searchPressed(_ sender: Any) { searchTF.endEditing(true) print(searchTF.text!) } @IBAction func addButtonPressed(_ sender: UIButton) { // 回调时携带餐段参数 delegate?.updateLogCalories(mealType: currentMealType, calStr: logCals) self.dismiss(animated: true) } } class LogViewController: UIViewController { @IBOutlet weak var breakfastLabel: UILabel! @IBOutlet weak var lunchLabel: UILabel! @IBOutlet weak var dinnerLabel: UILabel! @IBOutlet weak var totalCaloriesLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { let navController = segue.destination as! UINavigationController let destController = navController.topViewController as! SearchViewController // 接收按钮点击传递的餐段参数 guard let mealType = sender as? MealType else { return } destController.delegate = self destController.currentMealType = mealType } @IBAction func addBreakfastPressed(_ sender: UIButton) { // 替换为你故事板中segue的实际标识 performSegue(withIdentifier: "goToSearch", sender: MealType.breakfast) } @IBAction func addLunchPressed(_ sender: UIButton) { performSegue(withIdentifier: "goToSearch", sender: MealType.lunch) } @IBAction func addDinnerPressed(_ sender: UIButton) { performSegue(withIdentifier: "goToSearch", sender: MealType.dinner) } } extension LogViewController: DataDelegate { func updateLogCalories(mealType: MealType, calStr: String?) { // 根据餐段类型更新对应标签 switch mealType { case .breakfast: breakfastLabel.text = calStr case .lunch: lunchLabel.text = calStr case .dinner: dinnerLabel.text = calStr } // 可在这里添加总卡路里计算逻辑 } }
注意事项
- 需要提前在故事板中给跳转的segue设置标识,和代码中
performSegue的参数保持一致 - 如果需要累加卡路里而不是直接覆盖,可在LogViewController中新增对应餐段的数值存储属性,每次回调时累加后再赋值给Label
内容的提问来源于stack exchange,提问作者Abeer Nasir
相关产品推荐
相关产品推荐

