You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 16:33:02