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

如何通过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()
    }
}

核心问题分析

  1. 错误创建控制器实例:你在按钮点击事件中新建了一个HistroyCallsTableViewController对象,但界面上显示的是TabBarController中已存在的实例,数据传到了新对象而非显示中的实例。
  2. 数据添加时机错误: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:25:37