6

我一直在阅读文档,CAShapeLayer但我仍然不太明白。据我了解,Layer它总是平坦的,它的大小总是一个矩形。

CAShapeLayer另一方面,允许您定义一个不仅仅是矩形的层。它可以是圆形、三角形等,只要你使用它UIBezierPaths

我的理解到这里了吗?

我想到的是,例如,一个网球从屏幕边缘反弹(很容易),但我想显示一个不使用图像动画的小动画 - 我希望它显示一点“挤压“就像动画一样,因为它撞击屏幕边缘然后反弹。我没有使用网球图像。只是一个黄色填充的圆圈。

我在这里是正确的CAShapeLayer吗?如果是这样,你能提供一个小例子吗?谢谢。

4

1 回答 1

14

虽然您确实使用路径来定义图层的形状,但它仍然是使用用于定义框架/边界的矩形创建的。这是一个帮助您入门的示例:

网球.h:

#import <UIKit/UIKit.h>

@interface TennisBall : UIView

- (void)bounce;

@end

网球.m:

#import <QuartzCore/QuartzCore.h>
#import "TennisBall.h"

@implementation TennisBall

+ (Class)layerClass
{
    return [CAShapeLayer class];
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setupLayer];
    }
    return self;
}

/* Create the tennis ball */
- (void)setupLayer
{
    CAShapeLayer *layer = (CAShapeLayer *)self.layer;
    layer.strokeColor = [[UIColor blackColor] CGColor];
    layer.fillColor = [[UIColor yellowColor] CGColor];
    layer.lineWidth = 1.5;

    layer.path = [self defaultPath];
}

/* Animate the tennis ball "bouncing" off of the side of the screen */
- (void)bounce
{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
    animation.duration = 0.2;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation.fromValue = (__bridge id)[self defaultPath];
    animation.toValue = (__bridge id)[self compressedPath];
    animation.autoreverses = YES;
    [self.layer addAnimation:animation forKey:@"animatePath"];
}

/* A path representing the tennis ball in the default state */
- (CGPathRef)defaultPath
{
    return [[UIBezierPath bezierPathWithOvalInRect:self.frame] CGPath];
}

/* A path representing the tennis ball is the compressed state (during the bounce) */
- (CGPathRef)compressedPath
{
    CGRect newFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width * 0.85, self.frame.size.height);
    return [[UIBezierPath bezierPathWithOvalInRect:newFrame] CGPath];
}

@end

现在,当您想使用它时:

TennisBall *ball = [[TennisBall alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
[self.view addSubview:ball];

[ball bounce];

请注意,这需要扩展,以便您可以从不同的角度“反弹”等,但它应该让您指向正确的方向!

于 2013-06-08T20:20:37.163 回答