简体   繁体   English

使用Segue从先前的View Controller传递到另一个View Controller时,数据变为Nil

[英]Data turns Nil when passing from previous View Controller going to another View Controller using Segue

I am about to pass data from a ViewController going to another ViewController using segue. 我即将使用segue将数据从ViewController传递到另一个ViewController When checking the data(event) from a variable thru breakpoint in the 1st View Controller the data(event) is not nil. 在第一个视图控制器中通过断点从变量检查数据(事件)时,数据(事件)不是nil。 But when I checked the 2nd View Controller the data(event) is nil . 但是当我检查第二个View Controller时 ,data(event)为nil I am confuse whether if the reason is, I have error in my codes or because of the error appeared in my console that says Unable to insert COPY_SEND . 我很困惑是由于原因,我的代码中有错误还是由于控制台中显示无法插入COPY_SEND的错误 Hope I can get some help from you. 希望我能从您那里得到一些帮助。 Thank you 谢谢

显示事件和密码的First View Controller具有数据

Second View Controller显示事件和密码为NIL

Segue from First View Controller 来自First View Controller的Segue

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "DashBoardViewController" {
        let dashBoardController = segue.destination as! DashBoardViewController
        dashBoardController.self.event = event
        dashBoardController.self.passcode = passcode
    }
}

Event and Passcode Turns Nil 事件和密码变为零

override func viewDidLoad() {
    super.viewDidLoad()
    guard event != nil, passcode != nil else {
        _ = SCLAlertView(appearance: appearance).showError("No Event Details", subTitle: "There's no event details, please logout and try again")
        return
    }
    showEventDetails()
}

showEventDetails showEventDetails

func showEventDetails() {
    DispatchQueue.main.async{
        self.eventNameLabel.text =  "\(self.event.name.uppercased())"
        self.locationLabel.text =  "\(self.event.location.uppercased())"
        if let dateStringFromDate = getFormattedStringFromDate(date: (self.event.startDateTime), formatString: "MMMM dd, yyyy/ hh:mm a") {
            self.dateTimeLabel.text = dateStringFromDate
        } else {
            self.dateTimeLabel.text = "-"
        }
    }
}

I am assuming you linked the segue which goes to DashBoardViewController on your submitButton by Interface Builder, which means when you are tapping on the submit button, the @IBAction func submitButton(_ sender: UIButton) { } gets called, where you check if your passcode is good to go and if so you are calling validateEventPasscode() which calls an API endpoint (asynchronous) and only there you are populating the self.event = event (line 187 in ViewController.swift). 我假设您已通过Interface Builder链接了连接到SubmitButton上DashBoardViewController的segue,这意味着当您点击@IBAction func submitButton(_ sender: UIButton) { }按钮时,会@IBAction func submitButton(_ sender: UIButton) { } ,在此检查您是否可以使用密码 ,如果要使用密码 ,则可以调用validateEventPasscode()来调用API端点(异步),然后仅在其中填充self.event = event (ViewController.swift中的第187行)。

Now, what really happens is that when you link a segue from a button by IB (interface builder), there will be a perform segue internally which we have to stop by overriding the following method in ViewController.swift : source 现在,真正的情况是,当您通过IB(Interface Builder中)从一个按钮链接SEGUE,会有一个内部执行SEGUE,我们必须停止通过重写ViewController.swift下面的方法:

func shouldPerformSegue(withIdentifier identifier: String, 
                 sender: Any?) -> Bool {
    return false
}

This way your call from line 190 - ViewController.swift: 这样,您从第190行开始的调用-ViewController.swift:

self.performSegue(withIdentifier: "showEventDashboard", sender: self)

is the one that fires: 是会触发的:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      if segue.identifier == "DashBoardViewController" {
         let dashBoardController = segue.destination as!  DashBoardViewController
         dashBoardController.event = event
         dashBoardController.passcode = passcode
     }
   }

You can test my theory by placing three breakpoints in ViewController.swift : 您可以通过在ViewController.swift中放置三个断点来测试我的理论:

  1. line 134 at validateEventPasscode() from submitButton IBAction func; 来自SubmitButton IBAction函数的validateEventPasscode()的第134行;
  2. line 190 at self.performSegue(withIdentifier: "showEventDashboard", sender: self) from validateEventPasscode() func; 190行来自validateEventPasscode()函数的self.performSegue(withIdentifier:“ showEventDashboard”,发送者:self);
  3. line 108 at dashBoardController.event = event from prepare(for segue, sender) func; 第dashBoardController.event =的第108行= prepare(for segue,sender)func中的事件;

Buggy order of execution: 1, 3, 2 - at the moment this I would expect if my theory is correct; 错误的执行顺序:1、3、2-目前,如果我的理论是正确的,我可以期待; Desired order of execution: 1, 2, 3. 所需执行顺序:1、2、3。

Long story short, you populate your self.event after you perfomSegue and go to the next screen , that's why your event is nil in the next VC . 长话短说,您在执行self.event之后填充perfomSegue并转到下一个屏幕 ,这就是为什么您的event在下一个VC中nil的原因。

I used as reference the ViewController.swift file from your repo: ViewController.swift 我将您的仓库中的ViewController.swift文件用作参考: ViewController.swift

Hope it helps, cheers! 希望能有所帮助,加油!

Replace your prepareForSegue method in FirstViewController with this 以此替换FirstViewController中的prepareForSegue方法

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "DashBoardViewController" {
        let dashBoardController = segue.destination as! DashBoardViewController
        dashBoardController.event = event
        dashBoardController.passcode = passcode
    }
}

you don't need to write 你不需要写

dashBoardController.self.event = event
dashBoardController.self.passcode = passcode

Just remove self from above two lines. 只需从两行上面删除自己

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM