Xcode
为实现封装采用自定义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; ///< 上升的速度
重写视图的- (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];
定时器的响应方法是同步界面刷新一直绘制水波纹,self.fOffsety属性用来控制显示,如下:- (void)displayLinkAction{ self.fOffsetx += self.fWidth * self.fSscale; if (self.fOffsety <= 0.01) { [self.displayLink invalidate]; self.displayLink = nil; } [self setNeedsDisplay];}
界面刷新会调用- (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];}
水波纹具体绘制如下,采用正弦函数进行曲线绘制。- (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];}
自定义View封装实现之后,在需要调用的地方实例化view加载到指定view上即可:WaveView *waveView = [[WaveView alloc] initWithFrame:CGRectMake(30, 100, 150, 150)]; [self.view addSubview:waveView];
最终实现效果如下: