来自另一个 viewController Swift 的 reloadData()

Posted

技术标签:

【中文标题】来自另一个 viewController Swift 的 reloadData()【英文标题】:reloadData() from another viewController Swift 【发布时间】:2021-01-27 00:18:31 【问题描述】:

我有两个viewControllers:第一个有一个tableView,第二个有一个带有动作的textField,如果在textFiled中插入了特定的文本,我想调用loadData1()具有@987654322的函数@从logInviewController重新加载tableView,但是当我调用它时它返回nil。

tableViewController 代码:

    import UIKit
    import FirebaseFirestore
    import Firebase
    import FirebaseAuth

    class orderTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate 

    @IBOutlet var orderTable: UITableView!
    var db: Firestore!
    var firstName = [String]()
    var lastName = [String]()

    override func viewDidLoad() 
        super.viewDidLoad()
        
    orderTable.register(UINib(nibName: "Order1TableViewCell", bundle: nil) , forCellReuseIdentifier: "orderCell")

     
    
     func loadData1() 
        
      Firestore.firestore().collection("hola").getDocuments()  [self]
            
            (querySnapshot, err) in
            
            if let err = err
            
            
                print("Error getting documents: \(err)");
            
            else
            
     for document in querySnapshot!.documents 
                    self.firstName.append(document.get("firstname") as? String ?? "")
                    self.lastName.append(document.get("lastname") as? String ?? "")
      
     
            
            orderTable.reloadData()       // from here i got Unexpectedly found nil while unwrapping an Optional value:
     
      
     

    
    

logInViewController 代码:

    import UIKit
    import Firebase
    import FirebaseAuth

    class logInViewController: UIViewController, UITextFieldDelegate 
    
    
    @IBOutlet var userNameField: UITextField!
    @IBOutlet var passwordField: UITextField!
    @IBOutlet var logInButton: UIButton!
    var db: Firestore!
    var order: orderTableViewController!
    
    override func viewDidLoad() 
    super.viewDidLoad()
        

    
    
    @IBAction func textfieldDidChange(_ sender: Any) 
        
        print(userNameField?.text ?? "") 

        if userNameField.text == "v@v.com" 
            let i = orderTableViewController()
            i.loadData1()
            
          
      
    


    

【问题讨论】:

你应该大写你的类名。当您致电orderTableViewController() 时,我不清楚您期望发生什么。这不应该是对您的表格视图的引用吗?为什么称它为方法? @jn_pdx 因为我想在 logInViewController 中调用 loadData1() 并从 orderTableViewController 调用 loadData1() 但是您只是在创建它的一个新实例并在其上调用 loadData1() 吗?你不应该在order 上打电话吗? @jn_pdx 是的,我试过了,它给了我同样的错误 您没有在呈现数据的地方显示表格视图代码。如果你像你说的那样得到found nil while unwrapping an Optional value,你需要显示你在哪里强制解开一个可选的(寻找! 【参考方案1】:

你有let i = orderTableViewController(),你不是在引用你现有的表格视图控制器,而是在创建一个新的,除了这次它没有与情节提要场景一起实例化,因此你所有的@IBOutlet引用将为零。尝试引用这些 @IBOutlet 引用将失败。

要解决这个问题,您应该将第一个视图控制器的引用传递给第二个视图控制器,使用协议而不是显式的类名,然后第二个视图控制器可以调用第一个视图控制器中的方法。因此:

    创建类协议,例如LoginViewControllerDelegate:

    protocol LoginViewControllerDelegate: class  
    

    给该协议一种方法要求,loadData1

    protocol LoginViewControllerDelegate: class  
        func loadData1()
    
    

    使您的第一个视图控制器符合该协议:

    extension OrderTableViewController: LoginViewControllerDelegate  
        func loadData1() 
            ... your implementation here ...
        
    
    

    在第二个视图控制器中创建一个属性,即LoginViewController,用于此委托协议引用,例如:

    weak var delegate: LoginViewControllerDelegate?
    

    当第一个视图控制器实例化第二个时,设置此 delegate 属性(例如,如果进行 segue,它将在 prepareForSegue 中):

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        if let destination = segue.destination as? LoginViewController 
            destination.delegate = self
        
    
    

    然后第二个视图控制器将调用delegate?.loadData1() 而不是i.loadData1()

【讨论】:

【参考方案2】:

如果你按照我的理解去做,那么你就可以做到。但是你应该使用委托或闭包回调来做到这一点。

@IBAction func textfieldDidChange(_ sender: Any) 
    
    print(userNameField?.text ?? "") 

    if userNameField.text == "v@v.com" 
      if let i = order 
        i.loadData1()
       
    
  

【讨论】:

以上是关于来自另一个 viewController Swift 的 reloadData()的主要内容,如果未能解决你的问题,请参考以下文章

来自另一个 viewController Swift 的 reloadData()

从另一个 ViewController 调用一个 ViewController 的实例方法

访问视图来自另一个类的Controller元素

将图像放入 UIImageView(另一个 ViewController)时出错

从Swift中的另一个ViewController访问rightBarButton函数

如何通过来自同一个 TableViewController 的多个 segue 到同一个 ViewController