对于循环被一次性调用而不是递增Swift Xcode(不是UIBezierCurve)

时间:2018-03-09 20:00:45

标签: ios swift cocoa-touch drawing

每当我调用这个函数时,不是逐步遍历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)
}

1 个答案:

答案 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

}