2
votes

I'm working on a macOS App that uses auto-layout in a view hierarchy with layer backed views. The App uses an NSStackView with several subviews that each feature a collapse/unfold button to resize the respective subview. Resizing of subviews is implemented by adding and removing layout constraints and an animation context is used to animate the size change. I implemented this as demonstrated on WWDC 2013, Session 213, starting at about minute 29:

@objc func disclosureToggeled(_ sender : Any) {
    if isCollapsed {
        self.addConstraint(collapseConstraint)
    }
    else {
        self.removeConstraint(collapseConstraint)
    }

    NSAnimationContext.runAnimationGroup({ context in
        context.allowsImplicitAnimation = true
        self.window?.layoutIfNeeded()
    })
}

The resize animation works as expected.

My problem: if I trigger a resize animation and a subview containing a focussed UI element is animated into a new position its focus ring immediately jumps from its starting to its final position while the UI element itself animates correctly.

Any idea what I am doing wrong?

1
Thanks. But I've seen other apps (e.g. OmniFocus for Mac) that seem to accomplish animations in focus rings. I wonder how they do it. - mschmidt
You mean the superview of the NSStackView? Yes it is. - mschmidt
Well, I'm no help; all I can tell you is that I've had a lot of trouble with NSStackView animation using the technique you describe, to the extent that in one app I just gave up on NSStackView altogether. - matt

1 Answers

0
votes

I believe that this has to do with the issue that is discussed in that same video (jumpy window resize). The solutions, also discussed in the video are to either

  1. Animate constraint constant (rather than add/remove constraint) explicitly through the constraint.animator.constant accessor or
  2. Separately animate first the constraint in question, then the window frame, while keeping the constraint priority below the window resize priority so that animating the constraint doesn't resize the window.

I found approach 1 to be simpler if the constraint changes can be described by simple constant changes.