问题
So I have one UIViewController and two SKScenes. The UIViewController present the two scenes by rotating the device; landscape load SKScene 1 and portrait load SKScene 2 lie this:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
print("TRIGGERED")
if UIDevice.current.orientation.isLandscape {
print("Landscape")
presentView(name: "GameScene")
} else {
print("Portrait")
presentView(name: "GameScene2")
}
super.viewWillTransition(to: size, with: coordinator)
}
func presentView(name: String) {
if let view = self.view as! SKView? {
if let scene = SKScene(fileNamed: name) {
scene.scaleMode = .aspectFill
view.presentScene(scene)
}
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
This works fine. My dilema, however, is that I want to implement a delegate-protocol pattern between the two SKScenes GameScene and GameScene2. The problem is that the UIViewController (self) of SKScene 1 should be passed as the delegate to the SKScene 2. So if the user for instance click something in landscape mode (GameScene), som data String is passed over to GameScene2 when orientation is changed to portrait.
So in SkScene 1:
protocol MyProtocol {
func myProtocolFunc(someString: String)
}
class GameScene: SKScene{
var myDelegate: MyProtocol!
and in the UIViewController how do I set the delegate? scene.myDelegate doesn't work. GameScene().myDelegate = GameScene2().self works but since view.presentScene(scene) is used to present the scene that's not relevant. How do I access and set the delegate? How do I set up the delegate-protocol pattern so that I get the desired result?
回答1:
Using Swift 5:
protocol MyProtocol: AnyObject {
func myProtocolFunc(someString: String)
}
class GameScene: SKScene {
weak var myDelegate: MyProtocol?
init(fileNamed: String) {
super.init(fileNamed: fileNamed)
}
}
Then you have to create the scene object in your presentView method as a GameScene, not a SKScene (as you did). So instead of:
if let scene = SKScene(fileNamed: name) // wrong
you have to:
if let scene = GameScene(fileNamed: name) // correct
and then you can easily set the delegate with scene.myDelegate
来源:https://stackoverflow.com/questions/59769348/how-do-you-use-the-delegate-protocol-pattern-with-spritekit