I draw a wave layer by override drawInContext:(CGContextRef)ctx
method,since the wave line is sine-wave, so I cut it into segments by calculating wave value and join them into CGMutablePathRef
Here is what I have done in -(void)drawInContext:(CGContextRef)ctx
//join style
CGContextSetLineJoin(ctx, kCGLineJoinRound);
CGContextSetLineCap(ctx, kCGLineCapRound);
CGContextSetAllowsAntialiasing(ctx, true);
CGContextSetShouldAntialias(ctx, true);
CGContextSetFillColorWithColor(ctx, [UIColor themeColor].CGColor);
CGContextSetStrokeColorWithColor(ctx, [UIColor themeColor].CGColor);
CGContextSaveGState(ctx);
CGMutablePathRef mutablePath = CGPathCreateMutable();
CGPathMoveToPoint(mutablePath, NULL, 0, 0);
CGPathAddLineToPoint(mutablePath, NULL, 0, [self getSinPoint:0 WaveHeight:self.waveHeight]);
//Calculate the Sin funciton value to draw lines and join them into path
for (float i = 0; i <= self.bounds.size.width; i+= 1) {
NSInteger pointY = [self getSinPoint:i WaveHeight:self.waveHeight];
CGPathAddLineToPoint(mutablePath, NULL, i, pointY);
}
CGPathAddLineToPoint(mutablePath, NULL, self.bounds.size.width, 0);
CGPathCloseSubpath(mutablePath);
[[UIColor themeColor]set];
CGContextAddPath(ctx, mutablePath);
CGContextFillPath(ctx);
CGContextRestoreGState(ctx);
One solution is using BezierPath to draw the wave, 1.cut the line into segment such as 20 2.if current line index is event, get the control point below the center of the current segment 3.if current line index is odd,then get the control point up the center of the line
...
for (NSInteger i = 0; i <= self.waveCount; i++) {
CGPoint beginPoint = CGPointMake(i * self.waveWidth, pointY);
CGPoint endPoint = CGPointMake((i + 1) * self.waveWidth, pointY);
if (i%2 == 0) {
CGPoint controlPoint = [self getCenterControlPointUp:beginPoint End:endPoint];
CGPathAddQuadCurveToPoint(mutablePath, NULL, controlPoint.x, controlPoint.y, endPoint.x, endPoint.y);
}else{
CGPoint controlPoint = [self getCenterControlPointDown:beginPoint End:endPoint];
CGPathAddQuadCurveToPoint(mutablePath, NULL, controlPoint.x, controlPoint.y, endPoint.x, endPoint.y);
}
}
...
method to get the control point of a segment line
//Below
-(CGPoint)getCenterControlPointDown:(CGPoint)begin End:(CGPoint)end{
return CGPointMake((begin.x + end.x)/2, (begin.y + end.y)/2 + self.waveHeight * 2);
}
//Above
-(CGPoint)getCenterControlPointUp:(CGPoint)begin End:(CGPoint)end{
return CGPointMake((begin.x + end.x)/2, (begin.y + end.y)/2 - self.waveHeight * 2);
}