为什么执行 segue 后我的属性和网点变为零?

Why do my properties and outlets become nil after performing a segue?

我正在学习 Swift,目前在一个项目中使用两个 ViewController。第一个控制器初始化数据并执行到第二个的 segue。第二个 ViewController 将一个新值添加到从第一个 ViewController 传入的变量中。但是,当我关闭 segue 并尝试更新第一个时,所有 IBOutlet 属性和变量突然变为 nil。这是通过在 firstViewController 的 updateViewController() 方法中记录属性得出的。提前谢谢你。

第一个ViewController

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {


    // Date Label
    @IBOutlet weak var dateLabel: UILabel!

    // Progress Bar
    @IBOutlet weak var progressBar: UIProgressView?

    // Progress Label
    @IBOutlet weak var progressLabel: UILabel!

    // Button Collection View
    @IBOutlet weak var collectionView: UICollectionView!

    // Current goal button
    @IBOutlet weak var currentGoal: UIButton!

    // Goal label
    @IBOutlet weak var goalLabel: UILabel!

    // Variable Initialization

    // Initialize daily water goal
    var dailyGoal = Float(20)

    // Initialize current progress
    var currentProgress = Float()

    // Water counter variable
    var waterDrank = Float(0)

    var percentageProgress = Float(0.0)

    override func viewDidLoad() {
        super.viewDidLoad()

    progressBar?.setProgress(0.0, animated: false)
        progressBar!.transform = progressBar!.transform.scaledBy(x: 1, y: 3)

    }

    // MARK: - Button & Progress View Logic

    func addProgress(amount: Float) {

        // Add amount to the total amount drank
        waterDrank += amount
        print(waterDrank)

        // Get the current progress in relation to the daily goal
        let currentProgress = waterDrank / dailyGoal
        // Set the new progress to the progressBar
        progressBar?.setProgress(currentProgress, animated: true)

        // Check if progress is below 0

        if (dailyGoal - waterDrank) <= 0.0 {
        // done
        }

        // Check if the daily goal has already been achieved
        if waterDrank >= Float(dailyGoal) {

            // Daily goal has been achieved - show message & abort code
            showAlert(title: "done", message: "!!")

            return

        }

    }

        // MARK: - Segue Action

    // Segue button to second view controller
    @IBAction func changeGoal(_ sender: Any) {

        performSegue(withIdentifier: "currentGoal", sender: self)

    }

    // Save variables
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        let secondViewController = segue.destination as! SecondViewController
        secondViewController.dailyGoal = self.dailyGoal

    }

    func updateViewController() {

        // Log new daily goal
        print(dailyGoal)

        // Print progressBar object
        print(waterDrank) // is 0, despite waterDrank having been increased in value before performing segue

        print(progressBar?.progress) // is nil, despite having not been nil before performing segue

    }



}

第二个ViewController

    // Current goal label
    @IBOutlet weak var currentGoal: UILabel!

    // Goal picker
    @IBOutlet weak var goalPicker: UIPickerView!


    var dailyGoal = Float()

    let newDailyGoal = [Int()]

    // Initialize current progress
    var currentProgress = Float()

    // Water counter variable
    var waterDrank = Float(0)

    var percentageProgress = Float(0.0)

    override func viewDidLoad() {
        super.viewDidLoad()

    // setting secondViewController as delegate & data source for the UIPicker
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

        let vc = ViewController()
        let newDailyGoal = [1500, 1750, 2000, 2250, 2500]
        // Consider row

            switch row {

            case 0:
                self.dailyGoal = Float(newDailyGoal[0])
                vc.dailyGoal = self.dailyGoal

            case 1:
                self.dailyGoal = Float(newDailyGoal[1])
                vc.dailyGoal = self.dailyGoal

            case 2:
                self.dailyGoal = Float(newDailyGoal[2])
                vc.dailyGoal = self.dailyGoal

            case 3:
                self.dailyGoal = Float(newDailyGoal[3])
                vc.dailyGoal = self.dailyGoal

            case 4:
                self.dailyGoal = Float(newDailyGoal[4])
                vc.dailyGoal = self.dailyGoal

            default:

                print("daily goal is default: \(dailyGoal)")

            }


        // Export to ViewController.swift
        return "\(Int(dailyGoal)) ml"

    }

    // MARK: - Save button segue logic

    @IBAction func doneButton(_ sender: Any) {

        dismiss(animated: true, completion: nil)
        let firstViewController = ViewController()
        firstViewController.updateViewController()

    }

}

您的方案要求您将 ViewController 实例传递给 SecondViewController,而不是像您在此处所做的那样创建一个新实例。然后在完成按钮操作中调用函数 updateViewController。所以这是您需要更新的内容。

在ViewController中:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let secondViewController = segue.destination as! SecondViewController
    secondViewController.dailyGoal      = dailyGoal
    secondViewController.viewController = self
}

第二个ViewController:

class SecondViewController: UIViewController {
    weak var viewController: ViewController?
...

    @IBAction func doneButton(_ sender: Any) {
        dismiss(animated: true)
        viewController?.updateViewController()
    }
}