【发布时间】:2016-10-25 02:13:30
【问题描述】:
我一直在试图弄清楚如何在这个项目中使用 UIBezierPath,但我不知道如何实现这种绘图。我可以画一个圆、圆弧和直线,但我对这个感到很迷茫。感谢帮助
【问题讨论】:
标签: swift uibezierpath
我一直在试图弄清楚如何在这个项目中使用 UIBezierPath,但我不知道如何实现这种绘图。我可以画一个圆、圆弧和直线,但我对这个感到很迷茫。感谢帮助
【问题讨论】:
标签: swift uibezierpath
要在名为path 的UIBezierPath 上绘制正弦波,请使用path.addLine(to:) 绘制多个线段。诀窍是将角度(0 到 360)转换为点的x 坐标,将sin(x) 转换为点的y 坐标。
这是一个例子:
class SineView: UIView{
let graphWidth: CGFloat = 0.8 // Graph is 80% of the width of the view
let amplitude: CGFloat = 0.3 // Amplitude of sine wave is 30% of view height
override func draw(_ rect: CGRect) {
let width = rect.width
let height = rect.height
let origin = CGPoint(x: width * (1 - graphWidth) / 2, y: height * 0.50)
let path = UIBezierPath()
path.move(to: origin)
for angle in stride(from: 5.0, through: 360.0, by: 5.0) {
let x = origin.x + CGFloat(angle/360.0) * width * graphWidth
let y = origin.y - CGFloat(sin(angle/180.0 * Double.pi)) * height * amplitude
path.addLine(to: CGPoint(x: x, y: y))
}
UIColor.black.setStroke()
path.stroke()
}
}
let sineView = SineView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
sineView.backgroundColor = .white
它在 Playground 中运行:
@Rob 更新了此代码,使其在 @IBDesignable 中添加了 @IBInspectable 属性,并添加了 periods 属性。看看他的回答here。
【讨论】:
didSet 属性观察器,在didSet 中调用self.setNeedsDisplay()。使用计时器每 1/30 秒左右更新一次属性。要使正弦波滚动,请添加一个角度 offset 属性,然后将高度计算更改为:let y = origin.y - CGFloat(sin((angle + offset)/180.0 * Double.pi)) * height * amplitude。
self.view.addSubview(sineView) 从应用程序 ViewController 运行这个示例
这允许您在矩形内放置一个正弦波:
func generateWave(cycles: Int, inRect: CGRect, startAngleInDegrees: CGFloat = 0) -> UIBezierPath {
let dx = inRect.size.width
let amplitude = inRect.size.height
let scaleXToDegrees = 1 / (inRect.size.width / 360.0 / CGFloat(cycles))
let path = UIBezierPath()
for x in stride(from: 0, to: dx + 5, by: 5) {
let y = sin(D2R(startAngleInDegrees + x * scaleXToDegrees)) * amplitude / 2
let p = CGPoint(x: x + inRect.origin.x, y: y + inRect.origin.y)
if x == 0 {
path.move(to: p)
} else {
path.addLine(to: p)
}
}
return path
}
动画:
override func update(_ currentTime: TimeInterval) {
shape?.removeFromParent()
let path = generateWave(cycles: 7, inRect: targetRect, startAngleInDegrees: currentStartAngle)
shape = SKShapeNode(path: path.cgPath)
shape!.strokeColor = .red
shape!.lineWidth = 1
self.addChild(shape!)
currentStartAngle += 5
}
【讨论】: