Core Animation CAConstraint Grid-Cell Layout

I really wanted to get a nice Grid Layout using CAConstraint, but I found the situation getting very complex very fast as each Cell needed to be able to reference the location of the last Cell and whether or not the Cell needed to drop down to a new Row, and at times needed to also reference the @”superlayer”. There has to be a better way, right?

CAConstraint Grid-Cell Layout with Animations

After a little digging around I was able to find an amazing Hot Chocolate blog post which showed a fantastic trick when laying out the Cells without having to reference the prior Cell. This approach takes advantage of knowing the Cell Row/Column position plus using the Scale: attribute of the CAConstraint on the @”superlayer” and it works like a charm.

[CAConstraint constraintWithAttribute: kCAConstraintWidth
relativeTo: @"superlayer"
attribute: kCAConstraintWidth
scale: 1.0 / columns
offset: 0]];

Want to change the number of Cells in the Grid? Modify these variables in this method:

- (void)layoutCellsInGridLayer:(CALayer *)layer {
	int columns = 6;
	int rows = 6;...

Also to give the project a little bit of “wow” here’s some random Y rotation on a Cell Layer:

- (void)setupFlipAnimationOnLayer:(CALayer *)layer {
	float duration = (float)frandom(0.5, 5.0);
 
	CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
	animation.fromValue = [NSNumber numberWithDouble:-1.0f * M_PI];
	animation.toValue = [NSNumber numberWithDouble:1.0f * M_PI];
	animation.duration = duration;
	animation.repeatCount = 1e100f;
	animation.beginTime = CACurrentMediaTime() + frandom(0.1, 30);
	animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
 
	[layer addAnimation:animation forKey:@"rotationY"];
}

To get the nice 3D perspective look the project needs the following code:

- (void)setupPerspectiveWithX:(float)x andY:(float)y {
	CATransform3D transform = CATransform3DMakeRotation(x, 0, 1, 0);
	transform = CATransform3DRotate(transform, y, 1, 0, 0);
	float zDistance = -450;
	transform.m34 = 1.0 / -zDistance;
	gridLayer.sublayerTransform = transform;
}

And one last final note: take a look in createCellInParentLayer: and you will see layer.contents. If you can provide your own image the layer will automatically Fill (layer.contentsGravity = kCAGravityResizeAspectFill;) and Mask (layer.masksToBounds = YES;) to make it fit.

You can grab the code here or download the binary here (requires Leopard).

Tags: ,

3 Responses to “Core Animation CAConstraint Grid-Cell Layout”

  1. Stig Brautaset Says:

    Any chance you could link to the post in question rather than the front page of my blog? The direct link is: http://devblog.brautaset.org/2008/10/01/calayer...

  2. mozketo Says:

    Sorry for the mix up, I had a link to both your front page and the posting. I've now removed the offending link leaving only a link to your post. Thank you so much for your original post.

  3. Core Animation for automatic grid-cell layout « Cjed Audio blog Says:

    [...] grid-cell layout February 12, 2009 At Mozketo blog, we can find a great trick about automatic grid cell layout in Objective-C, using Core Animation CAConstraint. This example defines the width constraint on [...]