zoukankan      html  css  js  c++  java
  • iOS 水波效果

    将水波效果放在子视图上,主控制器只负责加载

    #import "WaveProgress.h"

    @interface WaveProgress ()

    @property (nonatomic,assign)CGFloat yHeight;/**< 当前进度对应的y值,由于y是向下递增,所以要注意 */

    @property (nonatomic,assign)CGFloat offset;/**< 偏移量,决定了这个点在y轴上的位置,以此来实现动态效果*/

    @property (nonatomic,strong)CADisplayLink * link;/**< 定时器*/

    @property (nonatomic,strong)CAShapeLayer * waveLayer;/**< 水波的layer */

    @property (nonatomic,assign)CGFloat speed;/**< 波动的速度*/

    @property (nonatomic,strong)UIColor * waveColor;

    @property (nonatomic,assign)CGFloat waveHeight;

    @end

    @implementation WaveProgress

    - (instancetype)initWithFrame:(CGRect)frame

    {

        self = [super initWithFrame:frame];

        if (self) {

            self.layer.borderColor = [UIColor lightGrayColor].CGColor;

            self.layer.borderWidth = 1.0f;

            

            self.waveHeight = 5.0;

            self.speed = 1.0;

            self.waveColor = [UIColor greenColor];

            self.waveLayer = [CAShapeLayer layer];

            self.waveLayer.frame = self.bounds;

            self.waveLayer.fillColor = [UIColor whiteColor].CGColor;

            [self.layer addSublayer:self.waveLayer];

            //由于y坐标轴的方向是由上向下,逐渐增加的,所以这里对于y坐标进行处理

            self.yHeight = self.bounds.size.height * 0.2;

            //先停止动画,然后在开始动画,保证不会有什么冲突和重复.

            [self stopWaveAnimation];

            [self startWaveAnimation];

        }

        return self;

    }

    #pragma mark -- 开始波动动画

    - (void)startWaveAnimation

    {

        //相对于NSTimer CADisplayLink更准确,每一帧调用一次.

        self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(waveAnimation)];

        [self.link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

    }

    #pragma mark -- 停止波动动画

    - (void)stopWaveAnimation

    {

        [self.link invalidate];

        self.link = nil;

    }

    #pragma mark -- 波动动画实现

    - (void)waveAnimation

    {

        CGFloat waveHeight = self.waveHeight;

        //如果是0或者1,则不需要wave的高度,否则会看出来一个小的波动.

        //    if (self.progress == 0.0f || self.progress == 1.0f) {

        //        waveHeight = 0.f;

        //    }

        //累加偏移量,这样就可以通过speed来控制波动的速度了.对于正弦函数中的各个参数,你可以通过上面的注释进行了解.

        self.offset += self.speed;

        CGMutablePathRef pathRef = CGPathCreateMutable();

        CGFloat startOffY = waveHeight * sinf(self.offset * M_PI * 2 / self.bounds.size.width);

        CGFloat orignOffY = 0.0;

        CGPathMoveToPoint(pathRef, NULL, 0, startOffY);

        for (CGFloat i = 0.f; i <= self.bounds.size.width; i++) {

            orignOffY = waveHeight * sinf(2 * M_PI / self.bounds.size.width * i + self.offset * M_PI * 2 / self.bounds.size.width) + self.yHeight;

            CGPathAddLineToPoint(pathRef, NULL, i, orignOffY);

        }

        //连接四个角和以及波浪,共同组成水波.

        CGPathAddLineToPoint(pathRef, NULL, self.bounds.size.width, orignOffY);

        CGPathAddLineToPoint(pathRef, NULL, self.bounds.size.width, self.bounds.size.height);

        CGPathAddLineToPoint(pathRef, NULL, 0, self.bounds.size.height);

        CGPathAddLineToPoint(pathRef, NULL, 0, startOffY);

        CGPathCloseSubpath(pathRef);

        self.waveLayer.path = pathRef;

        self.waveLayer.fillColor = self.waveColor.CGColor;

        CGPathRelease(pathRef);

    }

    @end

    在主控制器中就懒加载一次就可以

    - (WaveProgress *)progressView

    {

        if (!_progressView) {

            

            _progressView = [[WaveProgress alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 150)];

            

        }

        return _progressView;

    }

     效果图如下

  • 相关阅读:
    使用linux下的C操作SQLLITE
    s3c6410下移植sqlite3.7.8
    sqlite3在Linux下的安装和使用
    Linux下如何查看哪些进程占用的CPU内存资源最多
    查看LINUX进程内存占用情况
    ssh免密码登陆及其原理
    搭建zookeeper和Kafka集群
    HTTP 错误码
    time 命令
    Shell 运算相关
  • 原文地址:https://www.cnblogs.com/huiyi-520/p/6145403.html
Copyright © 2011-2022 走看看