Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

ViewController doesn't pass data on completion

I have 2 ViewControllers.

TimerViewController passes a variable to the EditTimerViewConroller. EditTimerViewConroller edits it and should pass it back, but it looks like code in .completion is not executed.

Any advice how to fix it?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

My code is:

TimerViewController

import UIKit
import AVFoundation //play sounds

class TimerViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()   
    }
    
    var player: AVAudioPlayer!
    var timer = Timer()
    var totalTime = 10.0
    var secondsRemaining = 10.0
    var secondsPassed = 0.0
    let timerStep = 0.1

    @IBOutlet weak var timerLabel: UILabel!
    
    
    @IBOutlet weak var progressBar: UIProgressView!
    
    @IBAction func startPressed(_ sender: UIButton) {
        //works fine
    }
    
    @IBAction func editTimerButtinPresed(_ sender: UIButton) {
        self.performSegue(withIdentifier: "goToEditTimer", sender: self)
        
        let editTimer = EditTimerViewController()
        editTimer.completion = { [weak self] duration in
            DispatchQueue.main.async {
                self?.totalTime = Double(duration!)
                print("editTimer completed, totalTime now is \(self?.totalTime)")
            }
        }
    }
    
    func playSound(fileName: String) {
        //works fine
    }
    
    @objc func updateTimer() {
        //works fine
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToEditTimer" {
            let destinationVC = segue.destination as! EditTimerViewController
            destinationVC.duration = Int(totalTime)
            print("Pasing duration = \(totalTime) to Edit screen")
        }
    }

EditTimerViewController

import UIKit

class EditTimerViewController: UIViewController {
    
    let maxDuration = 60
    var duration: Int? //timer duraton is passed from Timer
    public var completion: ((Int?) -> Void)?

    override func viewDidLoad() {
        super.viewDidLoad()
        durationSlider.minimumValue = 0
        durationSlider.maximumValue = Float(maxDuration)
        durationSlider.value = Float(duration!)
        
        durationLabel.text = String(duration!) + "s"
        }
    
    @IBOutlet weak var durationLabel: UILabel!
    @IBOutlet weak var durationSlider: UISlider!
    
    @IBAction func durationSliderChanged(_ sender: UISlider) {
        duration = Int(sender.value)
        print(duration!)
        durationLabel.text = String(duration!) + "s"
    }
    
    @IBAction func cancelPressed(_ sender: UIButton) {
        print("Cancel pressed, dismissing Edit screen")
        self.dismiss(animated: true, completion: nil)
    }
    
    @IBAction func savePressed(_ sender: UIButton) {
        print("Save pressed, duration is \(duration!)")
        completion?(duration!)
        self.dismiss(animated: true, completion: nil)

    }
}

In the output after pressing Save button I see

Save pressed, duration is 11

but after it there is no sign of

editTimer completed, totalTime now is 11

and timer duration never changes

>Solution :

Change

@IBAction func editTimerButtinPresed(_ sender: UIButton) {
    self.performSegue(withIdentifier: "goToEditTimer", sender: self)
    
    let editTimer = EditTimerViewController()
    editTimer.completion = { [weak self] duration in
        DispatchQueue.main.async {
            self?.totalTime = Double(duration!)
            print("editTimer completed, totalTime now is \(self?.totalTime)")
        }
    }
}

To

@IBAction func editTimerButtinPresed(_ sender: UIButton) {
    self.performSegue(withIdentifier: "goToEditTimer", sender: self) 
}

And move completion inside prepare

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "goToEditTimer" {
        let destinationVC = segue.destination as! EditTimerViewController
        destinationVC.duration = Int(totalTime)
        print("Pasing duration = \(totalTime) to Edit screen")
        destinationVC.completion = { [weak self] duration in
            DispatchQueue.main.async {
                self?.totalTime = Double(duration!)
                print("editTimer completed, totalTime now is \ (self?.totalTime)")
            }
         }
     }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading