With the observable property "didset" you can as its name indicates to monitor the change of value of a property in specific, even if the new value is the same as the current value of the property.
For example:
class MyButton : UIButton {
override var isSelected: Bool {
didSet {
print("Cambio de \(oldValue) a \(isSelected)")
}
}
}
let button = MyButton()
button.isSelected = true //se visualizaría en consola la impresión del mensaje
However, with this you would not be communicating a controller with another for this there may be different ways. One of them, as you mentioned, is to use a protocol.
* I did not understand very well how you have the communication from your controllers but I give you a simple example.
protocol CambioDelegate {
func cambioEstadoBoton(boton:UIButton)
}
class ButtonController: UIViewController {
weak var delegate: ViewController?
@IBOutlet weak var boton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func clicEnBoton(_ sender: Any) {
if boton.isSelected == true {
boton.isSelected = false
} else {
boton.isSelected = true
delegate?.cambioEstadoBoton(boton: boton)
}
}
}
class ViewController: UIViewController, CambioDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
func cambioEstadoBoton(boton: UIButton) {
print("Entra a cambio de estado")
}
}
Where the delegate reference could be given for example if there is a segue in your storyboard that is executed to show "ButtonController"
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "ButtonController" {
let vc = segue.destination as! ButtonController
vc.delegate = self
}
}