Swift:通过unwind segue传递的数据在被读取之前被删除

时间:2017-03-07 15:59:35

标签: ios iphone swift date segue

我尝试通过展开segue将Date从ViewController传递给另一个。问题是传递的数据被 Date()的结果替换。

以下是选择日期的VC代码:

class DateSelectorViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    ...

    @IBAction func validateDate(_ sender: CustomButton) {
        sendDateToNextVC(sender: sender)
    }   

    func sendDateToNextVC(sender: UIButton) {
        let destinationVC = AddActivityViewController()
        destinationVC.dateSelected = dateSelected
        destinationVC.recurrenceType = selectedFrequency
        destinationVC.isRecurrent = recurrent
        performSegue(withIdentifier: "sendSelectedDate", sender: sender)
    } 
}

以下是在 dateSelected 中接收日期的VC代码:

class AddActivityViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {

    ...    

    var dateSelected: Date = Date()

    ... 

    @IBAction func unwindToAddActiVC(_ sender: UIStoryboardSegue) {
        if sender.identifier == "sendSelectedDate" {
            setDateLabel()
        }
    } 

    func setDateLabel() {
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "fr_FR")
        dateFormatter.dateFormat = "dd MMMM yyyy"
        dateLabel.text = dateFormatter.string(from: dateSelected)
    }

}

我注意到了这行

var dateSelected: Date = Date()
多次调用

,特别是在此之后,日期从第一个VC传递到目标VC。我尝试使用可选项但它只会导致明显的错误" 在展开时找到了nil "。

如果您需要其他代码,请与我们联系。

提前致谢!!

3 个答案:

答案 0 :(得分:0)

sendDateToNextVC方法中,您创建了一个新的AddActivityViewController实例,然后将其丢弃。 iOS不知道它,它只是创建另一个实例。您将日期设置为您创建的实例,而iOS则继续使用自己的实例。

您应该使用prepareForSegue方法来传递日期。而不是自己创建VC,而是从prepareForSegue方法中的Segue对象中获取它。

它看起来像这样:

class DateSelectorViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    ...

    @IBAction func validateDate(_ sender: CustomButton) {
        sendDateToNextVC(sender: sender)
    }   

    func sendDateToNextVC(sender: UIButton) {
        let destinationVC = AddActivityViewController()
        destinationVC.dateSelected = dateSelected
        destinationVC.recurrenceType = selectedFrequency
        destinationVC.isRecurrent = recurrent
        performSegue(withIdentifier: "sendSelectedDate", sender: sender)
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destinationVC = segue.destinationViewController as? AddActivityViewController {
            destinationVC.dateSelected = dateSelected
            destinationVC.recurrenceType = selectedFrequency
            destinationVC.isRecurrent = recurrent
        }
    }
}

此处有更多详情:SO: How to pass prepareForSegue: an object

答案 1 :(得分:0)

DateSelectorViewController必须覆盖,

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "sendSelectedDate"{
        var vc = segue.destinationViewController as! AddActivityViewController
        vc.data = "Data you want to pass"
        //Data has to be a variable name in your AddActivityViewController
    }
}

答案 2 :(得分:0)

在这里,您实例化了一个新的 ViewController ,而不使用的是 Segue

这部分代码错误

func sendDateToNextVC(sender: UIButton) {
        let destinationVC = AddActivityViewController()
        destinationVC.dateSelected = dateSelected
        destinationVC.recurrenceType = selectedFrequency
        destinationVC.isRecurrent = recurrent
        performSegue(withIdentifier: "sendSelectedDate", sender: sender)
    } 

事实上,你正在创建一个新的viewController,segue已经完成了这项工作。

改为使用 prepareForSegue

 @IBAction func validateDate(_ sender: CustomButton) {
        sendDateToNextVC(sender: sender)
    }

    func sendDateToNextVC(sender: UIButton) {
        performSegue(withIdentifier: "sendSelectedDate", sender: sender)
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "sendSelectedDate",
            let destinationVC = segue.destinationViewController as? AddActivityViewController{
            destinationVC.dateSelected = dateSelected
            destinationVC.recurrenceType = selectedFrequency
            destinationVC.isRecurrent = recurrent
        }
    }

在这里你将获得segue中使用的viewcontroller,你的问题应该得到解决。

希望它有所帮助。

皮尔