Using KVO with existing Objective-C APIs

It's often useful to listen for frame or bounds changes, in order to resize other aspects.

Listening to frame changes can be done as follows:

let view = NSView(frame: .zero)

let observer = view
.observe(\NSView.frame) { (view, change) in
print("\(view.frame), \(change.oldValue) \(change.newValue)")
}

view.frame = NSRect(x: 0, y: 0, width: 100, height: 100)
// Later in code, in order to stop the observation
observer.invalidate()

The preceding code snippet will print the following:

(0.0, 0.0, 100.0, 100.0), nil nil

As you will note, both oldValue and newValue are nil. It is possible to use a different API if you are interested in the changes.

This is especially powerful when needing to recompute some available space, without the context. This helps isolate further, in line with all the patterns we are seeing in this section:

let view = NSView(frame: .zero)
view.observe(\NSView.frame, options: [.new, .old]) { (view, change) in
print("\(view.frame), \(change.oldValue!) -> \(change.newValue!)")
}
view.frame = NSRect(x: 0, y: 0, width: 100, height: 100)

Passing the options to the observer pattern lets you have old and new values passed to the changes. The preceding snippet will print as follows:

(0.0, 0.0, 100.0, 100.0), (0.0, 0.0, 0.0, 0.0) -> (0.0, 0.0, 100.0, 100.0)