Ios tableView.reloadData()和DispatchQueue无法在其他视图控制器中重新加载tableView

Ios tableView.reloadData()和DispatchQueue无法在其他视图控制器中重新加载tableView,ios,swift,uitableview,Ios,Swift,Uitableview,我有两个视图控制器,一个带有表视图(第一个是VC),另一个可以通过导航栏中的按钮导航到。第二个视图控制器应该能够将表视图单元添加到第一个视图控制器的表视图中 第一视图控制器: class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { let tableView = UITableView() var data = ["mars", "earth&

我有两个视图控制器,一个带有表视图(第一个是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
    }
}
第二视图控制器:

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与以前一样,没有使用新单元格重新加载和更新

图像:


如果需要实现此功能,最好使用协议以正确的方式链接这两个
视图控制器

在需要的任何位置创建协议:

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()
        }
   }
var textDelegate: PassingProtocol!
NewEntry
Barbutton
的操作中:

let myVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as! SecondViewController
    myVC.textDelegate = self
    self.navigationController?.pushViewController(myVC, animated: true)
    
}
textDelegate.saveData(withText: "New data added!")
第二视图控制器中

extension FirstViewController: PassingProtocol {
     func saveData(withText myText: String) {
       data.append(myText)
       DispatchQueue.main.async {
           self.tableView.reloadData()
        }
   }
var textDelegate: PassingProtocol!
然后在
didTapAddPostButton
的操作中:

let myVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as! SecondViewController
    myVC.textDelegate = self
    self.navigationController?.pushViewController(myVC, animated: true)
    
}
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()
        }
   }

}
二等控制员,斯威夫特

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!)

    }

}
通过协议,斯威夫特

import Foundation

    protocol PassingProtocol {
    func saveData(withText myText: String)
    }
迈塞尔,斯威夫特

import UIKit

class MyCell: UITableViewCell {

    @IBOutlet weak var lblData: UILabel!

}

它会起作用的,我自己也尝试过,效果很好。如果您需要实现它,最好使用协议以正确的方式链接这两个
视图控制器

在需要的任何位置创建协议:

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()
        }
   }
var textDelegate: PassingProtocol!
NewEntry
Barbutton
的操作中:

let myVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as! SecondViewController
    myVC.textDelegate = self
    self.navigationController?.pushViewController(myVC, animated: true)
    
}
textDelegate.saveData(withText: "New data added!")
第二视图控制器中

extension FirstViewController: PassingProtocol {
     func saveData(withText myText: String) {
       data.append(myText)
       DispatchQueue.main.async {
           self.tableView.reloadData()
        }
   }
var textDelegate: PassingProtocol!
然后在
didTapAddPostButton
的操作中:

let myVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as! SecondViewController
    myVC.textDelegate = self
    self.navigationController?.pushViewController(myVC, animated: true)
    
}
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()
        }
   }

}
二等控制员,斯威夫特

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!)

    }

}
通过协议,斯威夫特

import Foundation

    protocol PassingProtocol {
    func saveData(withText myText: String)
    }
迈塞尔,斯威夫特

import UIKit

class MyCell: UITableViewCell {

    @IBOutlet weak var lblData: UILabel!

}
它会起作用的,我自己也试过,效果很好,当你这样做时:

let FVC = FirstViewController()
。。。您正在创建一个新的、不相关的
FirstViewController
实例。这行不通。查看或(或显示您在何处演示的代码
SecondViewController
,我将更新我的答案)。

当您这样做时:

let FVC = FirstViewController()

。。。您正在创建一个新的、不相关的
FirstViewController
实例。这行不通。查看或(或显示您正在演示的位置的代码
SecondViewController
,我将更新我的答案)。

在画廊拍照后。将委托函数传递给FirstVC。
函数包含数据和数据计数。在调度队列方法中加载Tableview。

从库中拍照后。将委托函数传递给FirstVC。

函数包含数据和数据计数。在分派队列方法中加载Tableview。

您可以添加声明问题的图像吗?我已经添加了与问题无关的@menaim图像,但是
beginUpdates/endUpdates
performBatchUpdates
对于单个插入操作都是毫无意义的。除此之外,这两种形式都是同义词。检查我的更新答案,我认为这会解决问题。可以添加声明问题的图像吗?我已经添加了与问题无关的图像@menaim,但是
beginUpdates/endUpdates
performBatchUpdates
对于单个插入操作来说都是毫无意义的。除此之外,这两种形式都是同义词。检查我更新的答案,我想它会解决问题。我已经更新了我的帖子,加入了我在这里展示的代码SecondViewController@Hilardy我没看到…它在主帖子的“second view controller”下@Hilardy啊,我是说你展示second view controller的地方。最有可能是在
didSelectIndexAt
中。我已经更新了我的帖子,将我要展示的代码包括在内SecondViewController@Hilardy我没看到…它在主帖子的“second view controller”下@Hilardy啊,我是说你展示second view controller的地方。很可能是在
didSelectIndexAt
中。刚刚完成了它的实现。我收到错误
致命错误:隐式展开可选值时意外发现nil:file SecondViewController.swift,第34行
第34行是textDelegate.saveData()我现在将修改它检查新解决方案@HilardyI收到错误
在SecondViewControllercreate中的作用域中找不到类型“PassingProtocol”,我在解决方案中提到了这一点,并在解决方案中创建了它刚刚完成实现。我收到错误
致命错误:隐式展开可选值时意外发现nil:file SecondViewController.swift,第34行
第34行是textDelegate.saveData()我现在将修改它检查新解决方案@HilardyI收到错误
在SecondViewControllercreate中的作用域中找不到类型“PassingProtocol”。我在解决方案中提到了这一点,并且已经在解决方案中创建了它