Search code examples
swiftmacosanimationnsview

NSView Animation not animating


I'm trying to animate an NSView by changing the value of its leading constraint.

This is my constraint object:

@IBOutlet weak var vModDatesLeading: NSLayoutConstraint!

and the code I am using to animate its position:

@IBAction func getModDates(_ sender: Any) {
    
    NSAnimationContext.runAnimationGroup({ context in

        //Indicate the duration of the animation
        context.duration = 0.5
        vModDatesLeading.constant = 0
        vModDatesLeading.animator()
        vModDatesWrapper.layoutSubtreeIfNeeded()
       
       }, completionHandler:nil)
}

It is moving, but jumping, not animating. If this was iOS I would add:

view.layoutIfNeeded()

but that is not an option for NSView. I tried layoutSubtreeIfNeeded() but that did nada.

Any help would be appreciated.


Solution

  • I mostly work in iOS these days, and don't think I've ever used NSAnimationContext. I did a little digging, and it looks like you need to add the line

    context.current.allowsImplicitAnimation = true

    inside the body of your runAnimationGroup closure.

    Edit:

    I just noticed the line

    vModDatesLeading.animator()
    

    In your code. That doesn't do anything. The idea is that you should fetch an animator proxy for the object you are animating and apply your changes to that proxy. Thus your code should read:

    NSAnimationContext.runAnimationGroup({ context in
    
        //Indicate the duration of the animation
        context.duration = 0.5
        vModDatesLeading.animator().constant = 0
        vModDatesWrapper.layoutSubtreeIfNeeded()
    }
    

    (Note that I haven't tested this. I think that would work without needing the context.current.allowsImplicitAnimation = true, but I'd have to test it to be sure.)