Gold Challenge Using Delegate Pattern

If you wanted to make the date selection view controller reusable you wouldn’t want to bind it to an Item object. Instead you can define a delegate protocol and pass it the current date if there is one and have a dateChanged delegate method that must be implemented on the caller.

My implementation:

DetailViewController

class DetailViewController: UIViewController {
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        switch segue.identifier {
        case "changeDate"?:
            let changeDateViewController = segue.destination as! ChangeDateViewController
            changeDateViewController.date = item.dateCreated
            changeDateViewController.delegate = self
        default:
            preconditionFailure("Unexpected segue identifier.")
        }
    }
}

extension DetailViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

extension DetailViewController: ChangeDateDelegate {
    func dateChanged(_ date: Date) {
        item.dateCreated = date
    }
}

ChangeDateViewController

import UIKit

protocol ChangeDateDelegate {
    func dateChanged(_ date: Date)
}

class ChangeDateViewController: UIViewController {
    
    @IBOutlet var datePicker: UIDatePicker!
    
    var date: Date?
    var delegate: ChangeDateDelegate!
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        self.title = "Select Date"
        
        if let date = date {
            datePicker.date = date
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        if date != datePicker.date {
            delegate.dateChanged(datePicker.date)
        }
    }
}