微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

来自另一个 viewController Swift 的 reloadData()

如何解决来自另一个 viewController Swift 的 reloadData()

我有两个 viewController:第一个一个 tableView,第二个有一个带有动作的 textField,如果在 textFiled 中插入了特定的文本,我想调用 loadData1() 函数,它有orderTable.reloadData()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()
            
          }
      }
    


    }

解决方法

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

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

  1. 创建类协议,例如@IBOutlet

    LoginViewControllerDelegate
  2. 给该协议一个方法要求,protocol LoginViewControllerDelegate: class { }

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

    protocol LoginViewControllerDelegate: class { 
        func loadData1()
    }
    
  4. 在第二个视图控制器中创建一个属性 extension OrderTableViewController: LoginViewControllerDelegate { func loadData1() { ... your implementation here ... } } ,用于此委托协议引用,例如:

    LoginViewController
  5. 当第一个视图控制器实例化第二个时,设置此 weak var delegate: LoginViewControllerDelegate? 属性(例如,如果执行转场,它将在 delegate 中):

    prepareForSegue
  6. 然后第二个视图控制器将调用 override func prepare(for segue: UIStoryboardSegue,sender: Any?) { if let destination = segue.destination as? LoginViewController { destination.delegate = self } } 而不是 delegate?.loadData1()

,

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。