1

I'm making a game and everything's working fine. But there seems to be a problem with this custom button I made:

let button = UIButton(type: UIButtonType.Custom) as UIButton
let image = UIImage(named: "bluePlayButton")
button.setImage(image, forState: UIControlState.Normal)
button.frame = CGRectMake(self.size.width/2, self.size.height * 0.15, 300, 200)
button.layer.zPosition = 1

self.view?.addSubview(button)

When I run the application, the button just doesn't appear. What's wrong with my code, is there something missing?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Gabe12
  • 607
  • 1
  • 7
  • 25
  • 1
    What if the image is missing? `image` will be nil, the button won't have an image, there's no background, so there's nothing to see. – matt Apr 20 '16 at 02:36
  • @matt It's not, I've tried with many other images and tried adding ".png". Still doesn't work. – Gabe12 Apr 20 '16 at 02:40
  • Normally you don't need to set the z position. Try removing that line. – Slayter Apr 20 '16 at 03:14
  • @Slayter I added that line because I though the button may've stayed behind something else. It doesn't make a difference. – Gabe12 Apr 20 '16 at 03:39
  • @Gabe12 Did you try user36's suggestion? Use view debugging to see whether the button is actually there. – matt Apr 20 '16 at 03:48
  • 1
    Also, here's an idea: check to see whether `self.view` is nil. Because if it is, your `self.view?.addSubview` will do nothing — it won't throw an error or complain, but it won't add any subview. – matt Apr 20 '16 at 03:48
  • i suspect it's the frame. Can you try with `button.frame = CGRectMake(0, 0, 300, 200)` because that self.size value might not be correct and you are again adding as subview to UIViewController's self.view – Min Soe Apr 20 '16 at 15:37
  • This looks like you are inside of the `SKScene`, so where is this code being generated at? Does this code happen after the `SKScene` is presented to the view, or is it created in the init of the `SKScene`? Also, are you resizing your SKScene? Perhaps your SKSCene size is not the same size as your View, and the button is being thrown off of the view's bounds – Knight0fDragon Apr 20 '16 at 20:17

1 Answers1

1

I am currently integrating UI elements inside a sprite-kit scene, and i have to say that is a bit tricky. If you could give me more information about the other elements of the class, if is it a UIView or a SKScene (SKView), or a SKNode. When mixing both approaches this really is a pain.

But with the information you gave I can tell you that I have the same problem and I solved changing the method where a I added the UI elements on the SKScene. Before it was on the viewDidLoad but I should do it on the viewDidAppear.

EXAMPLE (Objective-C):

  • The iCarousel is a UI element (not SKView or SKNode).

`

-(void)didMoveToView:(SKView *)view {
//Your code but in Objective-C
UIButton * button  = UIButton
UIButton * button  = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage * image = [UIImage imageNamed:@"bluePlayButton"];
[button setImage:image forState:UIControlStateNormal];
[button setFrame:CGRectMake(self.size.width/2, self.size.height * 0.15, 300, 200)];
button.layer.zPosition=1;
[self.view addSubView:button];
}

`

  • Also, double check the zPosition of the button and the other elements.

  • Make really sure that the image is being loaded properly with the debugger. Even with the extension (.png) something might be happening to prevent so. ( as suggested by @matt on the comments)

  • I STRONGLY recommend to avoid mixing UIKit elements with Sprite-Kit elements.

  • Please give some more information if this does not solve your problem ;)

EDIT: Another example of how to do the the corresponding to UIButton in Sprite-Kit ( the most simple way).

(Just taken from this question - Setting up buttons in SKScene )

You could use a SKSpriteNode as your button, and then when the user touches, check if that was the node touched. Use the SKSpriteNode's name property to identify the node:

//fire button
- (SKSpriteNode *)fireButtonNode
{
    SKSpriteNode *fireNode = [SKSpriteNode spriteNodeWithImageNamed:@"fireButton.png"];
    fireNode.position = CGPointMake(fireButtonX,fireButtonY);
    fireNode.name = @"fireButtonNode";//how the node is identified later
    fireNode.zPosition = 1.0;
    return fireNode;
}

Add node to your scene:

[self addChild: [self fireButtonNode]];

Handle touches:

//handle touch events
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];

    //if fire button touched, bring the rain
    if ([node.name isEqualToString:@"fireButtonNode"]) {
         //do whatever...
    }
}
Community
  • 1
  • 1
  • Then, what's the best way to make a button in SpriteKit? – Gabe12 Apr 20 '16 at 15:11
  • There is no "Button" instance in Sprite-kit (dont know why), the most simple way in order to do so,is to make a `SKSpriteNode` and on 'touchesBegan' detect the touch on that node, and then do some action. (I found a quick example http://stackoverflow.com/questions/19082202/setting-up-buttons-in-skscene ). In my game I wrapped everything into a SKButton class ( made by me, not native of sprite-kit). – Felipe Cesar Assis Apr 20 '16 at 15:19
  • you should not be doing UIKit INSIDE of SpriteKit, there are reasons why you are getting so much trouble, they do not play well together. If you are using IB, design all of your view elements in that, if you want to design it all by code, subclass the SKView (Even though apple says not to do this, which I find silly) or do it in the ViewController class. If your entire screen is the SKScene, then I would not use UIKit at all, just create SKNodes that have userinteractionEnabled, but do not do it the way this answer does it (nodeAtPoint will only get you the top node), – Knight0fDragon Apr 20 '16 at 20:24
  • Instead use `let nodes = self.nodesAtPoint(location).filter({$0.userInteractionEnabled == true;});` to get all of the nodes that could be buttons, then use nodes.first to get the highest node (Which should be the button) and check the name here – Knight0fDragon Apr 20 '16 at 20:26
  • Would this let me change the image (or darken it) when it's being pressed like a normal button would? – Gabe12 Apr 21 '16 at 16:50
  • Could somebody pls answer this?^ – Gabe12 Apr 24 '16 at 21:51
  • In order to do this you will have to set it manually on `touchesBegan:` and `touchesEnded:` methods. On `touchesBegan:` you set a different state to the button ( texture, animation, color and etc..) and on `touchesEnded:` you restore the button to the original state . Of course there is many more sophisticated ways to do this (as making a separate SKButton structure), but the basics still the same specially regarding the "state " of the "SKButton". – Felipe Cesar Assis Apr 25 '16 at 13:24