On Aug 13, 2014, at 8:22 PM, Roland King <r...@rols.org> wrote:

> I have a constraint-based NSView layout which I can flip between states by 
> adjusting the constraint priorities and/or constants, and/or removing and 
> replacing some constraints. At the same time I make some views invisible or 
> visible again. All that stuff say is in a method on the view .. 
> 
>       -(void)updateConstraintsAndVariousViewPropertiesForState:(BOOL)state;
> 
> With the fairly straightforward UIView on iOS I’m used to doing this
> 
>       [ myUIView layoutIfNeeded ]
>       [ myUIView animateWithDuration:duration animations:^{
>               [ myUIView 
> updateConstraintsAndVariousViewPropertiesForState:state ];
>               [ myUIView layoutIfNeeded ];
>       } ];
> 
> The view properties change, the second layoutIfNeeded re-evaluates the 
> constraints and fixed up all the frames and bounds etc and the whole thing 
> animates smoothly to the new state. 
> 
> How do I do this with an *NSView*? 
> 
> Doing some docs diving I found animator proxies, get the proxy, call the 
> method on the proxy and it should animate. So I tried
> 
>       [ myNSView layoutSubtreeIfNeeded ];
>       [ myNSView updateConstraintsAndVariousViewPropertiesForState:state ];
>       [ [ myNSView animator ] layoutSubtreeIfNeeded ];
> 
> no animation, layout change, but no animation, just jumps. I put it in an 
> NSAnimationContext beginGrouping/endGrouping box … that didn’t help. Changing 
> some alpha properties in the same block did animate, but it seems the 
> layoutSubtreeIfNeeded doesn’t work with animator proxies. I tried just 
> setting constraint priorities using their animator proxies, that didn’t work 
> either, still just jumped. Looks like the only animator proxy able thing on a 
> constraint is the constant. So it looks like animator proxies aren’t going to 
> fly. 
> 
> Where do I go next? I see a few comments about layer-backed views, but 
> examples are few, do I need to back myself with a layer for this? 

As you discovered, you can set a constraint constant on the constraint's 
animator to animate that change in the constraint.  That doesn't work for 
priorities and really couldn't.  There's no in-between state with priorities.  
To the extent they matter at all, it's because it switches which constraints 
are in effect, and that's a binary condition.  When you set the constant on the 
animator, you're really animating the constraint, not the view positions.  The 
system adjusts the constraint a little bit, lays out the views according to the 
constraints, draws, adjusts the constraint some more, etc.

The alternative is to animate the view positions by doing something similar as 
in UIKit.  You make sure the frames are up-to-date with respect to the layout 
and then, in an animation group, you change the constraints and lay them out 
again.  The resulting view frame changes get animated.

It should work to do:

[view layoutSubtreeIfNeeded];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
    context.duration = 0.25; // you can leave this out if the default is 
acceptable
    context.allowsImplicitAnimation = YES;
    [view updateConstraintsAndVariousViewPropertiesForState:state];
    [view layoutSubtreeIfNeeded];
} completionHandler:nil];

This does require layer-backed views.  It may be that you can leave out setting 
allowsImplicitAnimation if you use the view's animator for the second 
-layoutSubtreeIfNeeded, but I'm not sure.  Supposedly, the animator turns on 
implicit animation, but I don't know if that's only when setting animatable 
properties.

Regards,
Ken


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to