Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scaling layer contents when animating layer-backed view

I'm animating a layer-backed view that contains several subviews. Everything is laid out using auto layout. Currently, as I animate the view, the subviews are not being scaled along with it:

animation

I'd like the whole thing to be drawn once, at their final size, then scaled as it animates. The layerContentsPlacement and layerContentsRedrawPolicy properties seem to be what I'm looking for, but changing them don't seem to have any effect.

Here's a basic run-through of how I'm doing the animation:

// Add itemView to canvas
NSView *itemView = // ...
itemView.layerContentsPlacement = NSViewLayerContentsPlacementScaleProportionallyToFit;
itemView.layerContentsRedrawPolicy = NSViewLayerContentsRedrawBeforeViewResize;
[parentView addSubview:itemView];

// Add constraints for the final itemView frame ...

// Layout at final state
[parentView layoutSubtreeIfNeeded];

// Set initial animation state
itemView.alphaValue = 0.0f;
itemView.frame = // centered zero'ed frame

// Set final animation state
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
  context.duration = 0.25f;
  context.allowsImplicitAnimation = YES;

  itemView.alphaValue = 1.0f;
  [parentView layoutSubtreeIfNeeded];
} completionHandler:nil];
like image 854
Joseph North Avatar asked Oct 04 '22 16:10

Joseph North


1 Answers

Thanks to David's comment I switched to using a transform on the view's layer.

The basic idea is to create and layout your view as you normally would, then create and add some CA animations to the view's layer.

// Add item view to canvas
NSView *itemView = // ...
[parentView addSubview:itemView];

// Add constraints for the final item view positioning

// Layout at final state
[parentView layoutSubtreeIfNeeded];

// Animate
CABasicAnimation *animation = [CABasicAnimation animation];
CATransform3D transform = CATransform3DMakeScale(0.5f, 0.5f, 0.5f);
animation.fromValue = [NSValue valueWithCATransform3D:transform];
animation.duration = 1.0f;
[itemView.layer addAnimation:animation forKey:@"transform"];

// create any other animations...
like image 157
Joseph North Avatar answered Oct 10 '22 04:10

Joseph North