iOS:CAShapeLayer 绘制非矩形图像并为其形状设置动画

Posted

技术标签:

【中文标题】iOS:CAShapeLayer 绘制非矩形图像并为其形状设置动画【英文标题】:iOS: CAShapeLayer to draw non-rectagular image and animating its shape 【发布时间】:2013-06-08 10:44:00 【问题描述】:

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

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

我的理解到这里了吗?

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

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

【问题讨论】:

【参考方案1】:

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

TennisBall.h:

#import <UIKit/UIKit.h>

@interface TennisBall : UIView

- (void)bounce;

@end

TennisBall.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];

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

【讨论】:

嘿,很高兴你发现这很有用。如果它回答了您的原始问题,那么请将其标记为正确答案并提出一个关于 UIImage 的新问题,因为它是一种完全不同的技术! 就像第一个球一样创建第二个球(通过创建TennisBall *ball2 = ... 并将其添加为子视图)。

以上是关于iOS:CAShapeLayer 绘制非矩形图像并为其形状设置动画的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 画布在非矩形部分裁剪并保存图像

脏矩形(高效绘图 13.3)

iOS“擦除”绘图与 CAShapeLayer 动画

拖动并缩放使用 UIBezierPath IOS/Swift 绘制的矩形

iOS绘制带有底部边框的自定义视图

iOS 动画虚线矩形边框