tableView.reloadData() 和 DispatchQueue 无法在不同的视图控制器中重新加载 tableview
Posted
技术标签:
【中文标题】tableView.reloadData() 和 DispatchQueue 无法在不同的视图控制器中重新加载 tableview【英文标题】:tableView.reloadData() and DispatchQueue not working to reload tableview in different view controller 【发布时间】:2021-05-31 16:41:27 【问题描述】:我有两个视图控制器,一个带有表格视图(第一个 VC),第二个可以通过导航栏中的按钮导航到。第二个视图控制器应该能够将一个表格视图单元格添加到第一个视图控制器的表格视图中。
第一个视图控制器:
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
let tableView = UITableView()
var data = ["mars", "earth", "jupiter", "venus", "saturn"]
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
view.addSubview(tableView)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.delegate = self
tableView.dataSource = self
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
tableView.frame = view.bounds
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return data.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = data[indexPath.row]
return cell
第二个视图控制器:
import UIKit
class SecondViewController: UIViewController
@IBOutlet var imageView: UIImageView!
@IBOutlet var button: UIButton!
@IBOutlet var addPostButton: UIButton!
override func viewDidLoad()
super.viewDidLoad()
title = "Second Screen"
// Do any additional setup after loading the view.
@IBAction func didTapButton()
let picker = UIImagePickerController()
picker.sourceType = .photoLibrary
picker.allowsEditing = true
picker.delegate = self
present(picker, animated: true)
@IBAction func didTapAddPostButton()
let FVC = FirstViewController()
FVC.data.append("New data added!")
DispatchQueue.main.async
FVC.tableView.beginUpdates()
FVC.tableView.performBatchUpdates(
FVC.tableView.insertRows(at: [IndexPath(row: FVC.data.count - 1,
section: 0)],
with: .automatic)
, completion: nil)
FVC.tableView.endUpdates()
print("TapAddPostButton pressed")
print(FVC.data)
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[UIImagePickerController.InfoKey.editedImage] as? UIImage else
return
imageView.image = image
应该发生什么:按下第二个视图控制器中的按钮后,应该添加一个新的表格单元格,然后重新加载表格视图。
实际情况: tableview 没有被重新加载。当我滑回第一个视图控制器时,tableview 和以前一样,并且没有重新加载和更新新单元格。
图片:
This is the first view controller
This is the second view controller
【问题讨论】:
你能添加声明问题的图片吗?? 我已经添加了图片@Menaim 与问题无关,但beginUpdates/endUpdates
和performBatchUpdates
对于单个插入操作都毫无意义。除此之外,这两种形式都是同义词。
查看我更新的答案,我认为它会解决问题
【参考方案1】:
当你这样做时:
let FVC = FirstViewController()
...您正在创建一个新的、不相关的 FirstViewController
实例。这行不通。查看delegates + protocols 或closures (或显示您在哪里展示SecondViewController
的代码,我会更新我的答案)。
【讨论】:
我已经更新了我的帖子以包含我展示 SecondViewController 的代码 它在“第二个视图控制器”下的主帖中 @Hilardy 啊我的意思是你展示 SecondViewController 的地方。最有可能在didSelectIndexAt
.【参考方案2】:
如果你需要实现它,最好使用协议能够以正确的方式链接这两个viewControllers
。
在您需要的任何地方创建协议:
protocol PassingProtocol
func saveData(withText myText: String)
然后在FirstViewController
:
extension FirstViewController: PassingProtocol
func saveData(withText myText: String)
data.append(myText)
DispatchQueue.main.async
self.tableView.reloadData()
在NewEntry
Barbutton
的行动中:
let myVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as! SecondViewController
myVC.textDelegate = self
self.navigationController?.pushViewController(myVC, animated: true)
在SecondViewController
:
var textDelegate: PassingProtocol!
那么在didTapAddPostButton
的动作中:
textDelegate.saveData(withText: "New data added!")
如果您需要使用插座,请按照以下步骤操作:
FirstViewController.Swift:
import UIKit
class FirstViewController: UIViewController
var data = ["mars", "earth", "jupiter", "venus", "saturn"]
@IBOutlet weak var tableViewOutlet: UITableView!
override func viewDidLoad()
super.viewDidLoad()
@IBAction func newEntryAction(_ sender: Any)
let myVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as! SecondViewController
myVC.textDelegate = self
self.navigationController?.pushViewController(myVC, animated: true)
extension FirstViewController : UITableViewDelegate, UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
data.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableViewOutlet.dequeueReusableCell(withIdentifier: "MyCell") as! MyCell
cell.lblData.text = data[indexPath.row]
return cell
extension FirstViewController: PassingProtocol
func saveData(withText myText: String)
data.append(myText)
DispatchQueue.main.async
self.tableViewOutlet.reloadData()
SecondViewController.Swift
import UIKit
class SecondViewController: UIViewController
@IBOutlet weak var textFieldData: UITextField!
var textDelegate: PassingProtocol!
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
@IBAction func addEntryButtonAction(_ sender: Any)
textDelegate.saveData(withText: textFieldData.text!)
PassingProtocol.Swift
import Foundation
protocol PassingProtocol
func saveData(withText myText: String)
MyCell.Swift
import UIKit
class MyCell: UITableViewCell
@IBOutlet weak var lblData: UILabel!
效果很好,我自己试过了,效果很好
【讨论】:
刚刚完成实施。我收到错误Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file SecondViewController.swift, line 34
第 34 行是 textDelegate.saveData()
我现在修改一下
检查新解决方案@Hilardy
我在 SecondViewController 中收到错误 Cannot find type 'PassingProtocol' in scope
创建它,我已经在解决方案中提到了这个并且已经在解决方案中创建了它【参考方案3】:
从画廊拍照后。将委托函数传递给 FirstVC。 FirstVC - 函数包含数据和数据计数。在调度队列方法中加载 Tableview。
【讨论】:
以上是关于tableView.reloadData() 和 DispatchQueue 无法在不同的视图控制器中重新加载 tableview的主要内容,如果未能解决你的问题,请参考以下文章
[tableView reloadData] 和 runloop
tableView.reloadData() 和 DispatchQueue 无法在不同的视图控制器中重新加载 tableview
Swift:tableView.reloadData() 表中没有数据
tableView reloadData 和 deselectRowAtIndexPath