如何通过TabBarController实现ViewController向UITableViewController无Segue传值(不切页)
问题解决:UITableViewController无法接收ViewController传递的数据
问题描述
我有一个带UIBarButtonItem的ViewController,点击按钮时需要将TextField的数据传递给同属一个TabBarController的UITableViewController,且无需切换到该UITableViewController。ViewController自带NavigationController,但当前代码无法正常工作:点击按钮后数据未保存,UITableViewController中仅显示空单元格。
原代码问题
ViewController中按钮点击事件代码
@IBAction func saveContact(_ sender: UIBarButtonItem) { let historyVC = HistroyCallsTableViewController() historyVC.userName = self.nameTextField.text ?? "Unknown" historyVC.userImage = self.imageView.image }
UITableViewController代码
struct Contact { var title: String var image: UIImage } class HistroyCallsTableViewController: UITableViewController { var contacts = [Contact]() var userName: String? var userImage: UIImage? override func viewDidLoad() { super.viewDidLoad() let contact = Contact(title: userName ?? "", image: userImage ?? UIImage()) contacts.append(contact) } // MARK: - Table view data source override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return contacts.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? ContactTableViewCell { cell.titleContactLabel.text = contacts[indexPath.row].title cell.contactPhotoimaveView.image = contacts[indexPath.row].image return cell } return UITableViewCell() } }
核心问题分析
- 错误创建控制器实例:你在按钮点击事件中新建了一个
HistroyCallsTableViewController对象,但界面上显示的是TabBarController中已存在的实例,数据传到了新对象而非显示中的实例。 - 数据添加时机错误:
viewDidLoad仅在控制器首次加载时执行一次,后续传递数据时不会触发该方法,导致新数据无法添加到contacts数组,表格也不会刷新。
解决方案
步骤1:获取TabBar中已存在的目标控制器实例
修改ViewController的按钮点击事件,从TabBarController的子控制器中找到已存在的HistroyCallsTableViewController:
@IBAction func saveContact(_ sender: UIBarButtonItem) { // 获取当前TabBarController guard let tabBarController = navigationController?.tabBarController else { return } // 遍历子控制器,找到目标实例 for vc in tabBarController.viewControllers ?? [] { // 处理目标控制器直接作为TabBar子控制器的情况 if let historyVC = vc as? HistroyCallsTableViewController { historyVC.userName = nameTextField.text ?? "Unknown" historyVC.userImage = imageView.image historyVC.addNewContact() return } // 处理目标控制器被包裹在NavigationController中的情况 if let navVC = vc as? UINavigationController, let historyVC = navVC.topViewController as? HistroyCallsTableViewController { historyVC.userName = nameTextField.text ?? "Unknown" historyVC.userImage = imageView.image historyVC.addNewContact() return } } }
步骤2:新增数据处理与表格刷新方法
修改HistroyCallsTableViewController,将数据添加逻辑抽成独立方法,并主动刷新表格:
struct Contact { var title: String var image: UIImage } class HistroyCallsTableViewController: UITableViewController { var contacts = [Contact]() var userName: String? var userImage: UIImage? override func viewDidLoad() { super.viewDidLoad() // 仅保留初始化逻辑,移除动态数据添加代码 } // 新增:添加新联系人并刷新表格 func addNewContact() { guard let name = userName, let image = userImage else { return } let contact = Contact(title: name, image: image) contacts.append(contact) tableView.reloadData() } // MARK: - Table view data source override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return contacts.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? ContactTableViewCell { cell.titleContactLabel.text = contacts[indexPath.row].title cell.contactPhotoimaveView.image = contacts[indexPath.row].image return cell } return UITableViewCell() } }
额外注意事项
- 确保Storyboard中TabBarController的子控制器配置正确,目标
HistroyCallsTableViewController实例已存在。 - 检查
ContactTableViewCell的复用标识符与Storyboard中的设置一致,避免cell加载失败。
内容的提问来源于stack exchange,提问作者SwiftCoder
相关产品推荐
相关产品推荐

