0

I am trying to do some fairly simple SKShapeNode math to set the position of a shape node. It looks like this:

    for var i = 0; i < 6; i++ {
        var pip: Pip = pips[i]

        // set position
        let x: CGFloat = tray2.frame.size.width - (i + 1) * pip.frame.size.width - (i + 1) * 2
        let y: CGFloat = tray2.frame.size.height - pip.frame.size.height - 1
        pip.position = CGPointMake(x, y)

        tray2.addChild(pip)
    }

However, in the 'let x...' line, an error is produced: "NSNumber is not a subtype of UInt8". What am I doing wrong here?

zeeple
  • 5,509
  • 12
  • 43
  • 71
  • `for var i : CGFloat = 0` – Bryan Chen Jul 23 '14 at 01:20
  • You can't mix ints and floats. Breaking up the multiple calculations into well named intermediates helps find errors. As a side effect there is better understanding of what is being done when someone else reads the code (or even you next month). – zaph Jul 23 '14 at 01:48
  • @BryanChen Thanks for the idea, but I cannot make i a float since I use it to pick items out of an array. – zeeple Jul 23 '14 at 05:08
  • @Zaph This turned out to be the solution. I basically broke all of those formulas down into multiple tiny statements and the error vanished. Post this as the answer and I will select it. – zeeple Jul 23 '14 at 05:10
  • @user1639164 Posted as an answer. – zaph Jul 23 '14 at 12:05
  • @BryanChen Iterating over a floating point variable is not a good idea. You can't ever be sure if the last `i` is `5.9` or `6.1`. – Sulthan Jul 23 '14 at 12:07
  • @Zaph I only see two answers, neither posted by you... Thanks tho! – zeeple Jul 23 '14 at 15:38
  • I posted an answer and it was down voted, Since I could not duplicate your environment I could not test that my proposed implementation was correct and addressed the issue. So I deleted it. Your accepted choice is a good one. Consider adding your solution to your question or as an answer. – zaph Jul 23 '14 at 15:56
  • 1
    @Sulthan you are right. but in this case, IEEE754 guarantees the result to be exact number. – Bryan Chen Jul 23 '14 at 21:53

2 Answers2

1

The problem is that you cannot implicitly convert integers to floats. For example:

(i + 1) * pip.frame.size.width

this is invalid because i is an Int, i + 1 is an Int but pip.frame.size.width is a CGFloat. This would work in languages like Obj-C where i would be implicitly cast to CGFloat but Swift has no implicit casts, so we have to cast explicitly.

The simplest fix is to convert i into a CGFloat first:

let floatI = CGFloat(i)

and then

let x = tray2.frame.size.width - (floatI + 1) * pip.frame.size.width - (floatI + 1) * 2
Sulthan
  • 128,090
  • 22
  • 218
  • 270
0

Wrap the expression in a CGFloat initializer to address the compiler error

for var i = 0; i < 6; i++ {
    var pip: Pip = pips[i]

    // set position
    let x: CGFloat = CGFloat(tray2.frame.size.width - (i + 1) * pip.frame.size.width - (i + 1) * 2)
    let y: CGFloat = CGFloat(tray2.frame.size.height - pip.frame.size.height - 1)
    pip.position = CGPointMake(x, y)

    tray2.addChild(pip)
}
dayhacker
  • 63
  • 6
  • Hm. This did not work. I copied in your code snippet and got the very same error. Thanks though, I really appreciate your idea. I'll play around with variations on it. – zeeple Jul 23 '14 at 04:49