Wednesday, July 9, 2014

Auto Layout on OS X: Backwards Compatibility

Milen Dzhumerov:

Unfortunately, as it regularly happens on OS X, the need for maintaining backwards compatibility has lead to important differences and unexpected behaviour in the exact same API when compared to iOS.


The situation is slightly different on OS X – once Auto Layout is enabled, AppKit insists that the positions of all views be determined by the constraint system, even for views which are not referenced by any constraints. AppKit will flag any such layout as ambiguous, even though it is not in practice - all views part of the constraint system have well-defined positions. I consider this to be a bug, as I cannot see a reason why such hierarchies need to be flagged as ambiguous (in fact, it works just fine on iOS). The good news is that even though the layout is incorrectly deemed ambiguous, everything seems to be working fine.


While the difference seems small, it has a very important implication. The reason why -setFrame: is used on OS X is due to backwards compatibility, as a -center property does not (necessarily!) exist at the NSView level (it exists only when layer-based). But due to the introduction of Core Animation in a backwards compatible way, it means that when we have a layer-based view tree, the positions are ultimately stored by the CALayers. And crucially, calling -setFrame: on a CALayer is semantically different to calling -setBounds:, -setPosition: and -setAnchorPoint:.

CALayers do not really have a frame property, as frame is a function of bounds.size, anchorPoint, position and transform. So when Auto Layout sets the frame of the layer, it also resets the transform to the identity. This is an extremely important behavioural difference that needs repeating: Auto Layout on OS X resets -transform of the the auto laid-out CALayers, essentially turning it into a read-only constant. Obviously, this does not happen on iOS as -setFrame: is not used. This behaviour prevents us from using the transform property – e.g., we might want to scale or rotate views but Auto Layout will be overwriting the changes we apply.

Comments RSS · Twitter

Leave a Comment