Reputation: 811
So, I've got a fairly simple question regarding Classes and Functions in Swift.
Let's say I make an app with SpriteKit. I have a GameScene (SKScene), a GameViewController (UIViewController) and a main storyboard for the GameViewController.
If I wanted to have a button on top of my GameScene, I'd connect a button IBOutlet from the main storyboard to the GameViewController. But how can I set it up, so that if I touch the button I can call a function inside the GameScene?
Do I have to handle this with delegation or is there a simpler method?
EDIT:
To elaborate, the function I'd like to call is:
func resetScene(){
self.removeAllActions()
self.removeAllChildren()
}
I tried to declared as a class func
but somehow it doesn't quite work.
Upvotes: 5
Views: 8072
Reputation: 531
There are basically four ways of calling a function from an other class.
Instance of the class. If you have an instance of say class Object, you can call Object's methods over that instance like myObject.buttonTapped().
By delegation: Create a protocol for class A and declare the method in the protocol. Class A must have an instance of the protocol. Call that method in the buttonTapped method like delegate.notifyButtonTapped(). In class B, conform to the protocol and implement the notifyButtonTapped() method.
Notification: Post a notification over NotificationCenter from class A and addObserver to in class B for that notification. Check this link for further information.
You can go with the delegation here. Check this link from rw for clarification.
Upvotes: 5
Reputation: 35392
I don't like the way how you reset the SKScene
, usually you can present the same scene to have a really cleaned scene, but I don't know your code so maybe I'm wrong.
About to how to access to the viewController of your scene you could find many ways as for example the protocol/delegate method but another one of them could be:
extension UIView {
func getViewController<T: UIViewController>() -> T? {
var responder = self.next
while responder != nil {
if let viewController = responder as? T {
return viewController
}
responder = responder!.next
}
return nil
}
}
And to use it :
if let gameVC = self.view?.getViewController(), gameVC is GameViewController {
let vc = gameVC as! GameViewController
print("That's all folks \(vc)")
}
Upvotes: 4
Reputation: 391
Making assumptions here, if your GameViewController contains a reference to your GameScene then you can do this quite easily. You can create an IBAction reference with a given method name buttonTapped
. Inside this method you can then call a method on your GameScene that performs the actions you are looking to do
// GameViewController
@IBAction func buttonTapped(sender: UIButton) {
self.gameScene.reactionMethod()
}
// GameScene
public func reactionMethod() {
// TODO: Do actions here
}
Upvotes: 0