0

So whenever I have this:

let result = SKScrollingNode(color: UIColor.clearColor(), size:CGSizeMake(CGFloat(containerWidth), image.size.height));

I get a compilation error for the image.size.height, telling me that "'UIImage?' does not have a member named 'size' although it does

Any idea what this means and how to fix it?

Thanks!

Entire code fragment:

class func scrollingNode(imageNamed: String, containerWidth: CGFloat) -> SKScrollingNode {
    let image = UIImage(named: imageNamed);

    let result = SKScrollingNode(color: UIColor.clearColor(), size: CGSizeMake(CGFloat(containerWidth), image.size.height));
    result.scrollingSpeed = 1.0;

    var total:CGFloat = 0.0;
    while(total < CGFloat(containerWidth) + image.size.width!) {
        let child = SKSpriteNode(imageNamed: imageNamed);
        child.anchorPoint = CGPointZero;
        child.position = CGPointMake(total, 0);
        result.addChild(child);
        total+=child.size.width;
    }
    return result;
Sarah
  • 313
  • 3
  • 10
  • 2
    `UIImage` has a `size`. `UIImage?` does not. – matt Nov 03 '14 at 15:36
  • Still doesn't work: UIImage.size.height. Getting the same error, so that's not the problem – Sarah Nov 03 '14 at 15:39
  • Take a look at this answer: http://stackoverflow.com/questions/26582035/in-xcode-6-1-uiimage-does-not-have-a-member-named-size-error – Rodrigo Borges Nov 03 '14 at 15:44
  • Can you please explain this bit: "Use optional chaining to unwrap the optional of image and use frame property of the UIImage." Don't quite get it. – Sarah Nov 03 '14 at 15:48
  • Can you please show it in my code? You can edit it if you want – Sarah Nov 03 '14 at 15:48

1 Answers1

4

In this line:

let image = UIImage(named: imageNamed)

image is an optional, UIImage?.

The error on this line:

let result = SKScrollingNode(color: UIColor.clearColor(), size: CGSizeMake(CGFloat(containerWidth), image.size.height));

can be narrowed down to this piece of code:

CGSizeMake(CGFloat(containerWidth), image.size.height)

CGSizeMake requires 2 CGFloat parameters, but the 2nd one is an optional, because image is an optional:

  • if image is not nil, image.size.height evaluates to a CGFloat
  • if image is nil, image.size.height evaluates to nil

In order to avoid that, you have 2 options:

  1. make image a non optional by using forced unwrapping

    let image = UIImage(named: imageNamed)!
    

    but I do not recommend using it because if the UIImage creation fails, the app will crash.

  2. Use optional binding:

    let image = UIImage(named: imageNamed);
    if let image = image {    
        let result = SKScrollingNode(color: UIColor.clearColor(), size: CGSizeMake(CGFloat(containerWidth), image.size.height));
        // ... rest of the code here
    }
    

    this is a better way to unwrap the optional, because in case it's nil, the code in the if statement will be skipped and no runtime error will occur.

Antonio
  • 71,651
  • 11
  • 148
  • 165