3

I'm relatively new in app development but for interest I want to implement this application on a playground project on Xcode:

http://merowing.info/2015/11/the-beauty-of-imperfection/

All the errors are corrected, but when I press the run Playground button it says "Running" forever without displaying anything. Do you know what I'm doing wrong?

import UIKit
import XCPlayground
import QuartzCore
import PlaygroundSupport

class Animator {
    class TargetProxy {
        init (target: Animator) {
            self.target = target
        }

        weak var target: Animator!
        var totalTime: TimeInterval = 0

        @objc func onFire (dl: CADisplayLink) {
            totalTime += dl.duration
            target.block(totalTime)
        }
    }

    private lazy var displayLink: CADisplayLink = {
        return CADisplayLink(target: TargetProxy(target: self), selector:      #selector(TargetProxy.onFire))}()
    private let block: (TimeInterval) -> Void

    init (block: @escaping (TimeInterval) -> Void) {
        self.block = block
        displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes)
    }

    deinit {
        displayLink.invalidate()
    }
}

func createBlobShape() -> UIBezierPath {
    let ovalPath = UIBezierPath()
    ovalPath.move(to: CGPoint.init(x: 13.71, y: -29.07))
    ovalPath.addCurve(to: CGPoint.init(x: 27.92, y: -14), controlPoint1:   CGPoint.init(x: 20.64, y: -25.95), controlPoint2: CGPoint.init(x: 24.57,   y: -20.72))
    ovalPath.addCurve(to: CGPoint.init(x: 33, y: 0.5), controlPoint1:  CGPoint.init(x: 30.08, y: -9.68), controlPoint2: CGPoint.init(x: 33, y:  -4.64))
    ovalPath.addCurve(to: CGPoint.init(x: 20.82, y: 26), controlPoint1:  CGPoint.init(x: 333, y: 10.93), controlPoint2: CGPoint.init(x: 27.47, y:  17.84))
    ovalPath.addCurve(to: CGPoint.init(x: 0, y: 33), controlPoint1:  CGPoint.init(x: 16.02, y: 31.88), controlPoint2: CGPoint.init(x: 7.63, y:  33))
    ovalPath.addCurve(to: CGPoint.init(x: -16.72, y: 28.33),  controlPoint1: CGPoint.init(x: -6.21, y: 33), controlPoint2:  CGPoint.init(x: -11.89, y: 31.29))
    ovalPath.addCurve(to: CGPoint.init(x: -23.86, y: 22), controlPoint1:  CGPoint.init(x: -19.59, y: 26.57), controlPoint2: CGPoint.init(x: -22.22,  y: 24.28))
    ovalPath.addCurve(to: CGPoint.init(x: -28, y: 17), controlPoint1:  CGPoint.init(x: -25.19, y: 20.16), controlPoint2: CGPoint.init(x: -26.74,  y: 19.46))
    ovalPath.addCurve(to: CGPoint.init(x: -33, y: 0.5), controlPoint1:  CGPoint.init(x: -30.24, y: 12.61), controlPoint2: CGPoint.init(x: -33, y:  5.74))
    ovalPath.addCurve(to: CGPoint.init(x: -23.86, y: -23), controlPoint1:  CGPoint.init(x: -33, y: -9.63), controlPoint2: CGPoint.init(x: -31.23, y:  -17.04))
    ovalPath.addCurve(to: CGPoint.init(x: -4.57, y: -33), controlPoint1:  CGPoint.init(x: -18.17, y: -27.6), controlPoint2: CGPoint.init(x: -12.51,  y: -33))
    ovalPath.addCurve(to: CGPoint.init(x: 13.71, y: -29.07),    controlPoint1: CGPoint.init(x: 0.32, y: -33), controlPoint2:      CGPoint.init(x: 9.53, y: -30.95))
    ovalPath.close()

    return ovalPath
}

func toRadian(degree: Int) -> Float {
    return Float(Double(degree) * (Double.pi / 180.0))
}

let blob = CAShapeLayer()
let blobShape = createBlobShape()
blob.path = blobShape.cgPath
blob.frame = blobShape.bounds
blob.anchorPoint = CGPoint.init(x: 0, y: 0)
blob.fillColor = UIColor.orange.cgColor

var view = UIView(frame: CGRect(x: 0, y: 0, width: 640, height:  480))
view.backgroundColor = UIColor.gray
//grayColor().colorWithAlphaComponent(0.8)
PlaygroundPage.current.liveView = view

blob.position = view.center
view.layer.addSublayer(blob)

let playImageView = UIImageView(image: UIImage(named: "play"))
playImageView.transform = CGAffineTransform.init(scaleX: 0.05, y:    0.05)
playImageView.center = blob.position
view.addSubview(playImageView)

PlaygroundPage.current.needsIndefiniteExecution = true
//XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

let dl = Animator {
    let skewBaseTime = $0 * 0.3

    let rotation = CATransform3DMakeRotation(CGFloat(acos(cos(skewBaseTime))), 0, 0, 1)
    let upscale = 5.0
    let scaleAdjustment = 0.1
    let scale = CATransform3DMakeScale(CGFloat(upscale +  abs(sin(skewBaseTime) * scaleAdjustment)), CGFloat(upscale +  abs(cos(skewBaseTime) * scaleAdjustment)), 1)

    let skewTransform = CGAffineTransform.init(a: 1.0, b: 0.0, c:  CGFloat(cos(skewBaseTime + Double.pi) * 0.1), d: 1.0, tx: 0.0, ty: 0.0)

    CATransaction.begin()
    CATransaction.setValue(kCFBooleanTrue, forKey:   kCATransactionDisableActions)
    view.layer.sublayerTransform =  CATransform3DConcat(CATransform3DMakeAffineTransform(skewTransform),   scale)
    blob.transform = rotation
    CATransaction.commit()
}
4
  • Unfortunately this is normal for Playgrounds. There's often no rhyme or reason. Commented Feb 8, 2018 at 20:10
  • That means, I won't get it run? Commented Feb 8, 2018 at 20:19
  • Try restarting Xcode. Commented Feb 8, 2018 at 20:53
  • Probably this link would be helpful to you stackoverflow.com/questions/39978092/… Commented Jun 5, 2018 at 13:13

3 Answers 3

1

Your code works. What you need to do is to open the "Assistant Editor" from the "View" menu to see the result.

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

0

You should correct:

private lazy var displayLink: CADisplayLink = {
    return CADisplayLink(target: TargetProxy(target: self), selector: #selector(TargetProxy.onFire))}()

With:

var displayLink: CADisplayLink {
    let target = TargetProxy(target: self)
    return CADisplayLink(target: target, selector: #selector(target.onFire))
}

2 Comments

I replaced it but it still doesn't show anything. However, at least I now see some numbers increasing (calculations going on) in the last part of the code (animation part). Any idea, why I don't see the bubble??
In dl = Animator(... change upscale value to 1.0 and you'll see something.
0

By default, Playgrounds are in sync with iCloud. Sometimes it can lead to this "stucks on "Running" bug.

Just go to:

System Preferences - Apple ID - Apps on this Mac using iCloud- iCloud Drive - Options- And then uncheck "Playground"

That little trick prevents syncing and resolves the frozen state of Xcode.

Prevent Playground from Sync

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.