使用Protocol/Delegate时IBOutlets相关问题求助
用 Protocol/Delegate 实现跨控制器传值的详细步骤
我来帮你梳理清楚用协议委托方案实现这个功能的每一步,比 segue 传值更灵活可控:
1. 定义传递数据的协议
首先在 LoLAddGoalsTableViewController 的代码顶部(类定义之前)声明一个协议,用来规定传递目标文本的方法:
protocol LoLAddGoalsDelegate: AnyObject { func didSaveGoal(withName goalName: String) }
这里用AnyObject是为了让委托只能是类类型,避免值类型引发的问题。
2. 在来源控制器中添加委托属性
在 LoLAddGoalsTableViewController 类里添加一个可选的委托属性,注意用weak修饰避免循环引用:
class LoLAddGoalsTableViewController: UITableViewController { @IBOutlet weak var nameOfRewardText: UITextField! // 声明委托属性 weak var delegate: LoLAddGoalsDelegate? // 点击Done按钮的触发方法 @IBAction func doneButtonTapped(_ sender: UIBarButtonItem) { // 先校验输入内容不为空 guard let goalText = nameOfRewardText.text, !goalText.isEmpty else { // 这里可以加个提示,比如弹个alert提醒用户输入目标内容 return } // 通过委托方法传递输入的目标文本 delegate?.didSaveGoal(withName: goalText) // 关闭当前控制器(如果是present方式弹出的话) dismiss(animated: true) } }
3. 让目标控制器遵守协议并实现方法
在 LoLGoalViewController 里,先遵守刚才定义的协议,然后实现协议方法来更新标签内容:
class LoLGoalViewController: UIViewController, LoLAddGoalsDelegate { @IBOutlet weak var currentGoalTextField: UILabel! // 跳转到添加目标控制器的触发方法(比如点击"添加目标"按钮) @IBAction func addGoalButtonTapped(_ sender: UIButton) { // 从storyboard获取添加目标控制器的实例 guard let addGoalVC = storyboard?.instantiateViewController(withIdentifier: "LoLAddGoalsTableViewController") as? LoLAddGoalsTableViewController else { return } // 设置委托为当前控制器 addGoalVC.delegate = self // 弹出控制器(如果是导航栈push的话,用navigationController?.pushViewController) present(addGoalVC, animated: true) } // 实现协议规定的方法 func didSaveGoal(withName goalName: String) { // 更新标签显示的文本 currentGoalTextField.text = goalName } }
4. 检查Storyboard配置要点
- 确保
LoLAddGoalsTableViewController在Storyboard中的Storyboard ID和代码里的实例化名称一致(上面例子里是"LoLAddGoalsTableViewController") - 确认两个控制器的IBOutlets(
nameOfRewardText、currentGoalTextField)都正确连接到了界面元素 - Done按钮的IBAction已正确关联到
doneButtonTapped方法
常见坑点提醒
- 委托属性必须加
weak,否则会导致两个控制器互相持有,引发内存泄漏 - 调用委托方法时用可选链式调用(
delegate?),避免委托未设置时崩溃 - 如果是用导航栈push跳转,替换弹出逻辑为
navigationController?.pushViewController(addGoalVC, animated: true)即可
这样设置完成后,用户在输入框输入目标并点击Done,文本就会实时传递到LoLGoalViewController并显示在对应的标签里啦!
内容的提问来源于stack exchange,提问作者Bob F.
相关产品推荐
相关产品推荐

