动画绘制水波纹
使用drawRect:方式绘制的动画效果,右图为占用了多少CPU.
虽然画起来挺好看的,但占用的内存真心吃不消,原因其实很简单哦,drawRect:方法只调用CPU进行图形绘制,所以非常非常的消耗CPU性能,把它集成到应用程序中,我觉得是不靠谱的呢.
//
// WaterView.h
// Cell
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface WaterView : UIView
@end
//
// WaterView.m
// Cell
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//
#import "WaterView.h"
@interface WaterView ()
{
UIColor *_currentWaterColor;
float _currentLinePointY;
float a;
float b;
BOOL flag;
}
@end
@implementation WaterView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self setBackgroundColor:[UIColor clearColor]];
a = 1.5;
b = 0;
flag = NO;
_currentWaterColor = [UIColor colorWithRed:86/255.0f
green:202/255.0f
blue:139/255.0f
alpha:1];
_currentLinePointY = 250;
[NSTimer scheduledTimerWithTimeInterval:0.02
target:self
selector:@selector(linkRun)
userInfo:nil
repeats:YES];
}
return self;
}
- (void)linkRun
{
if (flag) {
a += 0.01;
}else{
a -= 0.01;
}
if (a<=1) {
flag = YES;
}
if (a>=1.5) {
flag = NO;
}
b+=0.1;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
// 获取一个path
CGMutablePathRef path = CGPathCreateMutable();
{
// 移动到起始点
CGPathMoveToPoint(path, nil, 0, 100);
// 绘制水平方向上所有的点
float y = _currentLinePointY;
CGPathMoveToPoint(path, NULL, 0, y);
for(float x = 0; x <= 320; x++)
{
y= a * sin(x/180.f * M_PI + 4*b / M_PI) * 5 + _currentLinePointY;
CGPathAddLineToPoint(path, nil, x, y);
}
// 移动到屏幕底部
CGPathAddLineToPoint(path, nil, 320, rect.size.height);
CGPathAddLineToPoint(path, nil, 0, rect.size.height);
// 闭合曲线
CGPathAddLineToPoint(path, nil, 0, _currentLinePointY);
}
// 获取绘制句柄
CGContextRef context = UIGraphicsGetCurrentContext();
// 设置线宽为1
CGContextSetLineWidth(context, 1);
// 设置颜色为红色
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
// context接受path
CGContextAddPath(context, path);
// context填充path
CGContextFillPath(context);
// 描绘path
CGContextDrawPath(context, kCGPathStroke);
// 释放path
CGPathRelease(path);
}
@end
以下效果:
效率相差十万八千里呢,这是因为CoreAnimation使用GPU渲染,所以不仅流畅,还消耗CPU,如果配置的路径多一些,动画效果将会非常流畅的.
//
// RootViewController.m
// Cell
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//
#import "RootViewController.h"
#import "YXGCD.h"
@interface RootViewController ()
@property (nonatomic, strong) GCDTimer *timer;
@end
@implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
// shapeLayer
CAShapeLayer *circleLayer = [CAShapeLayer layer];
circleLayer.frame = (CGRect){CGPointMake(0, 0), CGSizeMake(200, 200)};
circleLayer.position = self.view.center;
circleLayer.path = [self path1].CGPath;
circleLayer.fillColor = [UIColor redColor].CGColor;
circleLayer.strokeColor = [UIColor redColor].CGColor;
circleLayer.lineWidth = 2.f;
[self.view.layer addSublayer:circleLayer];
// 定时器
_timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
[_timer event:^{
static int i = 0;
if (i++ % 2 == 0)
{
CABasicAnimation *circleAnim = [CABasicAnimation animationWithKeyPath:@"path"];
circleAnim.removedOnCompletion = NO;
circleAnim.duration = 1;
circleAnim.fromValue = (__bridge id)(circleLayer.path);
circleAnim.toValue = (__bridge id)[self path2].CGPath;
circleLayer.path = [self path2].CGPath;
[circleLayer addAnimation:circleAnim forKey:@"animateCirclePath"];
}
else
{
CABasicAnimation *circleAnim = [CABasicAnimation animationWithKeyPath:@"path"];
circleAnim.removedOnCompletion = NO;
circleAnim.duration = 1;
circleAnim.fromValue = (__bridge id)(circleLayer.path);
circleAnim.toValue = (__bridge id)[self path1].CGPath;
circleLayer.path = [self path1].CGPath;
[circleLayer addAnimation:circleAnim forKey:@"animateCirclePath"];
}
} timeInterval:NSEC_PER_SEC];
[_timer start];
}
- (UIBezierPath *)path1
{
//// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(0.5, 38.5)];
[bezierPath addCurveToPoint: CGPointMake(124.5, 38.5) controlPoint1: CGPointMake(0.5, 38.5) controlPoint2: CGPointMake(74.82, 114.88)];
[bezierPath addCurveToPoint: CGPointMake(240.5, 38.5) controlPoint1: CGPointMake(174.18, -37.88) controlPoint2: CGPointMake(240.5, 38.5)];
[bezierPath addLineToPoint: CGPointMake(240.5, 120.5)];
[bezierPath addLineToPoint: CGPointMake(0.5, 120.5)];
[bezierPath addLineToPoint: CGPointMake(0.5, 38.5)];
[bezierPath closePath];
return bezierPath;
}
- (UIBezierPath *)path2
{
//// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(0.5, 38.5)];
[bezierPath addCurveToPoint: CGPointMake(124.5, 38.5) controlPoint1: CGPointMake(0.5, 38.5) controlPoint2: CGPointMake(64.14, -22.65)];
[bezierPath addCurveToPoint: CGPointMake(240.5, 38.5) controlPoint1: CGPointMake(184.86, 99.65) controlPoint2: CGPointMake(240.5, 38.5)];
[bezierPath addLineToPoint: CGPointMake(240.5, 120.5)];
[bezierPath addLineToPoint: CGPointMake(0.5, 120.5)];
[bezierPath addLineToPoint: CGPointMake(0.5, 38.5)];
[bezierPath closePath];
return bezierPath;
}
@end
不过,使用path路径动画绘制波形图需要考验你的空间感觉了.