I want to draw a moving sine wave with variable frequency and variable amplitude in a crisp and anti-aliased way. How is this possible?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
Well, I implemented sine wave into the UIView drawrect method as follows :
float x=75;
float yc=50;
float w=0;
while (w<=rect.frame.size.width) {
CGPathMoveToPoint(path, nil, w,y/2);
CGPathAddQuadCurveToPoint(path, nil, w+x/4, -yc,w+ x/2, y/2);
CGPathMoveToPoint(path, nil, w+x/2,y/2);
CGPathAddQuadCurveToPoint(path, nil, w+3*x/4, y+yc, w+x, y/2);
CGContextAddPath(context, path);
CGContextDrawPath(context, kCGPathStroke);
w+=x;
}
Here x would be the width of each sine wave, while y is the height of the frame. This would draw number of sine waves to fit in the whole UIViewFrame. It would produce crisp looking sine wave and yc being control handle. Try it you might like it.
If the width ie. x is similar to the width of the frame then a single sine wave will be produced.
Number of complete sine wave = (width of frame) / ('x' width of each sine wave)
回答2:
Made a more complete, and swift version of GeneratorOfOne's version. This one also fills the bottom of the wave with a chosen color:
class WaveView: UIView {
private var maskPath: UIBezierPath!
@IBInspectable var fillColor: UIColor = UIColor.blueColor()
@IBInspectable var cycles: CGFloat = 7
override func drawRect(rect: CGRect) {
var w: CGFloat = 0 // Starting position
let width = rect.width
let y: CGFloat = rect.height
let yc: CGFloat = rect.height / 2
let x = width/cycles
let context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, UIColor.greenColor().CGColor);
let path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, 0, 0)
while (w<=rect.width) {
CGPathMoveToPoint(path, nil, w,y/2);
CGPathAddQuadCurveToPoint(path, nil, w+x/4, -yc, (w+x/2), y/2);
CGPathMoveToPoint(path, nil, w+x/2,y/2);
CGPathAddQuadCurveToPoint(path, nil, w+3*x/4, y+yc, w+x, y/2);
w+=x;
}
CGPathAddLineToPoint(path, nil, rect.width, rect.height)
CGPathAddLineToPoint(path, nil, 0, rect.height)
CGPathAddLineToPoint(path, nil, 0, y/2);
CGPathCloseSubpath(path)
maskPath = UIBezierPath(CGPath: path)
maskPath.lineCapStyle = CGLineCap.Square
maskPath.lineJoinStyle = CGLineJoin.Miter
CGContextAddPath(context, path);
CGContextSetFillColorWithColor(context, fillColor.CGColor)
CGContextFillPath(context)
}
}