多语言展示
当前在线:503今日阅读:57今日分享:41

iOS如何实现水波纹动画加载效果

基于CADisplayLink定时器与正弦函数实现水波纹动画效果的绘制。
工具/原料

Xcode

方法/步骤
1

为实现封装采用自定义View的形式,.m先定义相关用的控制属性以及定时器,如下:@property (nonatomic, strong) CADisplayLink *displayLink;@property (nonatomic, assign) CGFloat fAmplitude; ///< 振幅@property (nonatomic, assign) CGFloat fCycle; ///< 周期@property (nonatomic, assign) CGFloat fHdistance; ///< 水平之间偏移@property (nonatomic, assign) CGFloat fVdistance; ///< 竖直之间偏移@property (nonatomic, assign) CGFloat fSscale; ///< 速度@property (nonatomic, assign) CGFloat fOffsety; ///< 波峰所在位置的y坐标@property (nonatomic, assign) CGFloat fWidth; ///< 移动的距离,配合速率设置@property (nonatomic, assign) CGFloat fOffsetx; ///< 偏移@property (nonatomic, assign) CGFloat fUPScale; ///< 上升的速度

2

重写视图的- (instancetype)initWithFrame:(CGRect)frame方法进行初始化相关操作,同时实例化定时器,如下:self.backgroundColor = [UIColor clearColor];    _progress = 0;    self.fAmplitude = self.frame.size.height / 25;    self.fCycle = 2 * M_PI / (self.frame.size.width * 0.9);    self.fHdistance = 2 * M_PI / self.fCycle * 0.6;    self.fVdistance = self.fAmplitude * 0.4;    self.fWidth = 0.5;    self.fSscale = 0.4;    self.fUPScale = 0.1;    self.fOffsety = (1 - _progress) * (self.frame.size.height + 2 * self.fAmplitude);       self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkAction)];    [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

3

定时器的响应方法是同步界面刷新一直绘制水波纹,self.fOffsety属性用来控制显示,如下:- (void)displayLinkAction{    self.fOffsetx += self.fWidth * self.fSscale;    if (self.fOffsety <= 0.01)    {        [self.displayLink invalidate];        self.displayLink = nil;            }    [self setNeedsDisplay];}

4

界面刷新会调用- (void)drawRect:(CGRect)rect方法进行绘制,在此方法里面结合UIBezierPath实现水波纹的实现,如下:    - (void)drawRect:(CGRect)rect{    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];    [[UIColor groupTableViewBackgroundColor] setFill];    [path fill];    [path addClip];        //绘制两个波形图    [self drawWaveColor:[UIColor colorWithRed:0/255.0 green:191/255.0 blue:255/255.0 alpha:1.0f] offsetx:0 offsety:0];    [self drawWaveColor:[UIColor colorWithRed:0/255.0 green:191/255.0 blue:255/255.0 alpha:0.4f] offsetx:self.fHdistance offsety:self.fVdistance];}

5

水波纹具体绘制如下,采用正弦函数进行曲线绘制。- (void)drawWaveColor:(UIColor *)color offsetx:(CGFloat)offsetx offsety:(CGFloat)offsety{    CGFloat end_offY = (1 - _progress) * (self.frame.size.height + 2 * self.fAmplitude);    if (self.fOffsety != end_offY) {        if (end_offY < self.fOffsety) {            self.fOffsety = MAX(self.fOffsety -= (self.fOffsety - end_offY) * self.fUPScale, end_offY);        }else {            self.fOffsety = MIN(self.fOffsety += (end_offY - self.fOffsety) * self.fUPScale, end_offY);        }    }        UIBezierPath *wavePath = [UIBezierPath bezierPath];    for (float next_x = 0.f; next_x <= self.frame.size.width; next_x ++) {        CGFloat next_y = self.fAmplitude * sin(self.fCycle * next_x + self.fOffsetx + offsetx / self.bounds.size.width * 2 * M_PI) + self.fOffsety + offsety;        if (next_x == 0) {            [wavePath moveToPoint:CGPointMake(next_x, next_y - self.fAmplitude)];        }else {            [wavePath addLineToPoint:CGPointMake(next_x, next_y - self.fAmplitude)];        }    }    [wavePath addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height)];    [wavePath addLineToPoint:CGPointMake(0, self.bounds.size.height)];    [color set];    [wavePath fill];}

6

自定义View封装实现之后,在需要调用的地方实例化view加载到指定view上即可:WaveView *waveView = [[WaveView alloc] initWithFrame:CGRectMake(30, 100, 150, 150)];    [self.view addSubview:waveView];

7

最终实现效果如下:

推荐信息