Search code examples
iosswiftuiviewuibuttonskscene

Adding target to UIButton for superview


I am adding a UIView programatically to an SKScene. In this UIView I have a button that should fire a command in the SKScene. How do I do this? My code throws an exception. Or perhaps this is just not clean programming?

class LevelAchievedView: UIView {

override init(frame: CGRect) {
        super.init(frame: frame)
        self.opaque = false
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func drawRect(rect: CGRect) {
        let replayButton = UIButton()
        replayButton.setTitle("Replay?", forState: UIControlState.Normal)
        replayButton.setTitleColor(UIColor.greenColor(), forState: UIControlState.Normal)
        replayButton.titleLabel!.font = UIFont(name: "HelveticaNeue-Light", size: 30)
        replayButton.addTarget(self.superview, action: "returnToStart", forControlEvents: .TouchUpInside)
        replayButton.frame.origin = CGPointMake(10, 10)
        self.addSubview(replayButton)
    }

It seems I am messing up replayButton.addTarget(self.superview... and I guess I cannot use self.superview in this case although I have the func returnToStart() in the SKScene. What am I missing?

The exception thrown:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SKView returnToStart]: unrecognized selector sent to instance 0x7ff10980fc00'

Solution

  • self.superview is not the SKScene. Just a solution:

    class LevelAchievedView: UIView {
        let replayButton: UIButton
    
        override init(frame: CGRect) {
            self.replayButton = UIButton()
    
            super.init(frame: frame)
            self.opaque = false
    
            replayButton.setTitle("Replay?", forState: UIControlState.Normal)
            replayButton.setTitleColor(UIColor.greenColor(), forState: UIControlState.Normal)
            replayButton.titleLabel!.font = UIFont(name: "HelveticaNeue-Light", size: 30)
            replayButton.frame.origin = CGPointMake(10, 10)
            self.addSubview(replayButton)
        }
    }
    
    class MyScene: SKScene {
        override func didMoveToView(view: SKView) {
            // ...
            let levelAchieved = LevelAchievedView(rect: CGRect(...))
            levelAchieved.replayButton.addTarget(self, action: "returnToStart", forControlEvents: .TouchUpInside)
            view.addSubview(levelAchieved)
        }
    
        func returnToStart() {
            // your code here
        }
    }