每当我调用这个函数时,不是逐步遍历for循环(所以它会通过for循环一次,画一条线,然后再次运行绘制下一行...),它会通过for循环一下子就把所有点同时绘制出来。我怎么能这样做,以便不是一次单独绘制线条?
func generateSpirograph(insideRadius: Double = 0.5, rotationalSpeed: Double = -31/3, color: UIColor = .blue) {
//Creates an 800*800 image that is transparent
let transparentImage = #imageLiteral(resourceName: "IMG_0002.JPG")
let imgCenter = CGPoint(x: transparentImage.size.width/2, y: transparentImage.size.height/2)
var multiplier: Double!
if insideRadius <= 1 {
multiplier = (2 - insideRadius)*100
} else {
multiplier = 150/insideRadius
}
//The size of the new bitmap
UIGraphicsBeginImageContext(transparentImage.size)
transparentImage.draw(at: .zero)
//Setup Context
guard let context = UIGraphicsGetCurrentContext() else { return }
context.move(to: CGPoint(x: multiplier*(1+insideRadius)+Double(imgCenter.x), y: Double(imgCenter.y)))
for t in 0 ... 50 {
let radians = Double(t) * Double.pi / 180
let x = (cos(radians)+insideRadius*cos(rotationalSpeed*radians))
let y = (sin(radians)+insideRadius*sin(rotationalSpeed*radians))
context.addLine(to: CGPoint(x: multiplier*x+Double(imgCenter.x), y: multiplier*y+Double(imgCenter.y)))
}
context.setLineWidth(5)
context.setStrokeColor(color.cgColor)
context.drawPath(using: .stroke)
guard let spirographImg = UIGraphicsGetImageFromCurrentImageContext() else { return }
UIGraphicsEndImageContext()
let spirographImageView = UIImageView(image: spirographImg)
spirographImageView.contentMode = .scaleAspectFit
let scaledHeight = (view.frame.width / 2) / spirographImg.size.width * spirographImg.size.height
spirographImageView.frame = CGRect(x: 0, y: 0, width: view.frame.width/2, height: scaledHeight)
view.addSubview(spirographImageView)
}
答案 0 :(得分:0)
添加CAShapeLayer类型的属性?到你的ViewController
weak var shapeLayer: CAShapeLayer?
你可以像这样使用UIBezierPath():
func generateSpirograph(insideRadius: Double = 0.5, rotationalSpeed: Double = -31/3, color: UIColor = .blue) {
//Creates an 800*800 image that is transparent
let transparentImage = #imageLiteral(resourceName: "avatar.png")
let imgCenter = CGPoint(x: transparentImage.size.width/2, y: transparentImage.size.height/2)
var multiplier: Double!
if insideRadius <= 1 {
multiplier = (2 - insideRadius)*50
} else {
multiplier = 150/insideRadius
}
//The size of the new bitmap
UIGraphicsBeginImageContext(transparentImage.size)
transparentImage.draw(at: .zero)
//Setup Context
let path = UIBezierPath()
path.move(to: CGPoint(x: multiplier*(1+insideRadius)+Double(imgCenter.x), y: Double(imgCenter.y)))
for t in 0 ... 300 {
let radians = Double(t) * Double.pi / 180
let x = (cos(radians)+insideRadius*cos(rotationalSpeed*radians))
let y = (sin(radians)+insideRadius*sin(rotationalSpeed*radians))
path.addLine(to: CGPoint(x: multiplier*x+Double(imgCenter.x), y: multiplier*y+Double(imgCenter.y)))
}
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor
shapeLayer.strokeColor = color.cgColor
shapeLayer.lineWidth = 5
shapeLayer.path = path.cgPath
view.layer.addSublayer(shapeLayer)
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.duration = 3
shapeLayer.add(animation, forKey: "animation")
// save shape layer
self.shapeLayer = shapeLayer
}