跨视图控制器调用tableView.reloadData()及DispatchQueue刷新表格无效问题
问题原因
- 你在第二个控制器的
didTapAddPostButton方法中手动新建了一个FirstViewController实例,该实例和导航栈中已经存在的、用户之前访问过的第一个控制器没有关联,修改这个全新实例的数据源和表格属性,不会对原有页面生效。 - 直接跨控制器操作另一个控制器的内部视图,会导致代码耦合度过高,不符合UIKit开发规范。
解决方法
推荐使用闭包回调的方式实现数据传递,逻辑简单且耦合度低,修改步骤如下:
- 给SecondViewController新增回调属性,修改添加按钮的点击逻辑:
import UIKit class SecondViewController: UIViewController { // 新增:用于传递新增数据的回调闭包 var addDataCompletion: ((String) -> Void)? @IBOutlet var imageView: UIImageView! @IBOutlet var button: UIButton! @IBOutlet var addPostButton: UIButton! override func viewDidLoad() { super.viewDidLoad() title = "Second Screen" } @IBAction func didTapButton(){ let picker = UIImagePickerController() picker.sourceType = .photoLibrary picker.allowsEditing = true picker.delegate = self present(picker, animated: true) } // 修改添加按钮的点击逻辑 @IBAction func didTapAddPostButton(){ // 触发回调,传递需要新增的内容 addDataCompletion?("New data added!") // 可选:点击后自动返回第一个控制器 navigationController?.popViewController(animated: true) print("TapAddPostButton pressed") } } // 原有扩展内容保持不变 extension SecondViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true, completion: nil) } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { picker.dismiss(animated: true, completion: nil) guard let image = info[.editedImage] as? UIImage else { return } imageView.image = image } }
- 在FirstViewController的跳转逻辑中,接收回调处理数据和表格刷新:
找到你原来跳转SecondViewController的代码(一般是导航栏按钮的点击方法),修改为如下逻辑:
// 你原有跳转第二个控制器的触发方法 @objc func jumpToSecondVC() { let secondVC = SecondViewController() // 实现回调,处理新增数据逻辑 secondVC.addDataCompletion = { [weak self] newContent in guard let self = self else { return } // 先更新数据源 self.data.append(newContent) // 主线程刷新表格 DispatchQueue.main.async { self.tableView.insertRows(at: [IndexPath(row: self.data.count-1, section: 0)], with: .automatic) } } navigationController?.pushViewController(secondVC, animated: true) }
如果是通过Storyboard Segue跳转,就把赋值逻辑放在prepare(for:sender:)方法中即可。
内容的提问来源于stack exchange,提问作者Hilardy
相关产品推荐
相关产品推荐

