Search code examples
iosswiftswift3calayer

Swift: CALayer bounds contains NaN: [nan nan; nan nan]?


I have no idea what is going on here despite looking at similar answers. I have made a custom UIImageview that is supposed to start animating as soon as it is created:

class HeaderAnimator: UIImageView {

    var travelUp = Bool(false)

    var img = UIImage()

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func layoutSubviews() {
        //init

        //ALWAYS SAME COLOR - black with less opacity, just change shapes randomly via parent
        self.image = img

        UIView.animate(withDuration: 1,
                       delay: 0.2,
                       options: UIViewAnimationOptions.curveEaseIn,
                       animations: { () -> Void in
                        //animate
                        if(self.travelUp)
                        {
                             self.center.y += screenSize.height * (50/screenSize.height)
                        }
                        else {
                            self.center.y -= screenSize.height * (50/screenSize.height)
                        }

        }, completion: { (finished) -> Void in
            // ....
            print("done")
            self.removeFromSuperview()
        })

Then Im trying to spawn these views on a timer in another view:

let rand = Double(arc4random_uniform(4))
       var bgTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.animateInBg), userInfo: nil, repeats: true)

func animateInBg()
    {
        var randPos = CGPoint()
        var upOrDown = Int(arc4random_uniform(UInt32(2)))
        //print(upOrDown)

        let h = HeaderAnimator(frame: CGRect(x: 0, y: 0, width: self.bounds.width * (40/self.bounds.width), height: self.bounds.width * (40/self.bounds.width)))
        h.img = UIImage(named: "rocket")!

        switch upOrDown {
        case 0: //down
            randPos = CGPoint(x: CGFloat(arc4random()).truncatingRemainder(dividingBy: ( self.bounds.width)), y: self.bounds.height * 0.9)
            h.travelUp = false
            //h.transform = CGAffineTransform(scaleX: 1, y: -1)

        case 1: //up
            randPos = CGPoint(x: CGFloat(arc4random()).truncatingRemainder(dividingBy: ( self.bounds.width)), y: self.bounds.height * 0)
            h.travelUp = true
        default:
            randPos = CGPoint(x: CGFloat(arc4random()).truncatingRemainder(dividingBy: ( self.bounds.width)), y: self.bounds.height * 0)
            h.travelUp = true
        }

        h.center = CGPoint(x: self.bounds.width * 0.5, y: 0)
        self.addSubview(h)
    }

These views are supposed to show up then move either up or down out of the view then delete. Shortly after one spawns however, I get error: CALayerInvalidGeometry CALayer bounds contains NaN: [nan nan; nan nan]

What does this mean? What am I doing wrong just creating these views?


Solution

  • Per Apple, you should not subclass UIImageView. Instead, they recommend that you subclass UIView and do your drawing there.

    Do not use image views for custom drawing. TheUIImageView class does not draw its content using the draw(_:) method. Use image views only to present images. To do custom drawing involving images, subclass UIView directly and draw your image there.