Как передать данные по таймеру в новый ViewController (Swift 3)

Я знаю, как передавать данные в новый ViewController. Проблема в том, что я не могу передать данные из таймера.

Следующий код работает для одного ViewController. Я пробовал несколько способов разбить код на два контроллера представления. Я попытался поместить таймер в SecondViewController. Я пытался только передать начальную дату выбора. Я попытался поместить функции внутри функций.

Текущая проблема заключается в том, что я не могу передать totalSeconds, потому что он определен в таймере. Если я инициализирую функцию вне таймера, скажем, в 0, она просто возвращает значение 0. Если я передаю datePicker или компоненты даты, я сталкиваюсь с подобной проблемой, когда я определяю интервалы времени в SecondViewController. Например, функция updateTimer не будет распознавать значения, переданные в ViewDidLoad() SecondViewController.

Любая помощь с благодарностью. Я просто хочу поместить строки в updateTimer() в SecondViewController.

    class ViewController: UIViewController {

    @IBOutlet weak var datePicker: UIDatePicker!
    @IBOutlet weak var Output: UILabel!
    @IBOutlet weak var Output4: UILabel!
    @IBOutlet weak var Output3: UILabel!
    @IBOutlet weak var Output2: UILabel!
    @IBOutlet weak var timePicker: UIDatePicker!
    @IBOutlet weak var Output5: UILabel!
    @IBOutlet weak var Output6: UILabel!

    var birthDate = DateComponents()

    @IBAction func timePickerChanged(_ sender: Any) {

    let tComponents = Calendar.current.dateComponents([.hour, .minute], from: (sender as AnyObject).date)
    birthDate.hour = tComponents.hour
    birthDate.minute = tComponents.minute
}

    @IBAction func datePickerChanged(_ sender: Any) {
    let components = Calendar.current.dateComponents([.year, .month, .day], from: (sender as AnyObject).date)
    birthDate.year = components.year
    birthDate.month = components.month
    birthDate.day = components.day
}

    override func viewDidLoad() {
    super.viewDidLoad()

    Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.updateTimer), userInfo: nil, repeats: true)

    // Do any additional setup after loading the view, typically from a nib.
}

    func updateTimer(){
    let now = Date()

    let birthDay = userCalendar.date(from: birthDate)!

    let totalSeconds = Int(now.timeIntervalSince(birthDay))

    let totalMinutes = userCalendar.dateComponents([.minute], from: birthDay, to: now)

    let totalHours = userCalendar.dateComponents([.hour], from: birthDay, to: now)

    let totalDays = userCalendar.dateComponents([.day], from: birthDay, to: now)

    let totalWeeks = userCalendar.dateComponents([.weekOfYear],from: birthDay, to: now)

    let totalMonths = userCalendar.dateComponents([.month], from: birthDay, to: now)

    Output.text = String(totalSeconds)
    if totalMinutes.minute != nil {
        Output2.text = String(totalMinutes.minute!)
    }
    if totalHours.hour != nil {
        Output3.text = String(totalHours.hour!)
    }
    if totalDays.day != nil{
        Output4.text = String(totalDays.day!)
    }
    if totalWeeks.weekOfYear != nil{
        Output5.text = String(totalWeeks.weekOfYear!)
    }
    if totalMonths.month != nil{
        Output6.text = String(totalMonths.month!)
    }

}
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    updateTimer()
    let secondsController = segue.destination as! SecondViewController
    secondsController.finalSeconds = totalSeconds
}

1 ответ

@CJW ,

Знаете ли вы о концепции протоколов и делегатов. Вы можете легко решить вышеуказанную проблему, используя делегаты и протоколы.

1. Создайте протокол в своем первом классе viewcontroller как

protocol TimerUpdateDelegate {
    func updateTotalSeconds(_ iTotalSeconds : Int)
}

2. Создайте переменную для делегата как

var delegate : TimerUpdateDelegate?

3. Теперь добавьте ниже строку кода в вашем updateTimer метод контроллера первого вида.

        if self.delegate != nil 
         {self.delegate?.updateTotalSeconds(totalSeconds)}

в приведенной выше строке кода, которая totalSeconds будет вашим расчетным значением в себе updateTimer функция как параметр.

4. Теперь импортируйте делегат во второй класс viewcontroller как,

         class ViewController: UIViewController,TimerUpdateDelegate {}

5. В методе ViewDidload добавьте следующий набор строк:

override func viewDidLoad() {
  firstViewController.delegate = self
  }

6. Определите методы TimerUpdateDelegate в вашем контроллере представления второго класса:

    func updateTotalSeconds(_ iTotalSeconds : Int)
            {
                self.finalSeconds = iTotalSeconds
            }

Я надеюсь, что это решит вашу проблему.

Другие вопросы по тегам