Reputation:
I am trying to change the text of a field on a button cick the button is getting called but the label displayed the old text.
If I use NSUserDefaults to save the value then I will have to close the app and reopen it to see the new value of text field.
Is there any way when a user presses a button the value gets reset instantaneously on the screen?
GameViewController Code
import UIKit
import SpriteKit
class GameViewController: UIViewController {
@IBOutlet var resetText: UIButton!
@IBAction func ResetTextPreseed(sender: AnyObject) {
GameScene().changeText()
}
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GameScene(fileNamed:"GameScene") {
// Configure the view.
let skView = self.view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
}
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return .AllButUpsideDown
} else {
return .All
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
GameScene Code
import SpriteKit
class GameScene: SKScene {
let myLabel = SKLabelNode(fontNamed:"Chalkduster")
var text = "Hello, WOrld"
override func didMoveToView(view: SKView) {
/* Setup your scene here */
myLabel.text = text
myLabel.fontSize = 45
myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
self.addChild(myLabel)
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
func changeText(){
text = "I got changed"
myLabel.text = text
self.addChild(myLabel)
print ("The value of text is \(text)")
}
}
Upvotes: 1
Views: 79
Reputation: 13675
Currently, what you are doing will not work because you are not referencing the current scene but rather making a new instance of a GameScene
scene and calling changeText()
method on that instance, which has no effect on a current scene.
There is always a debate about should you or shouldn't use UIKit
elements with SpriteKit
. I would not go into that topic, but in general, SpriteKit and UIKit are different beasts and even if I really like both frameworks I would stick to SpriteKit only as much as I can when it comes to games ... And about some differences... For example, there is a difference between how SKScene renders its nodes vs how views are rendered. Some quotes from docs :
In the traditional view system, the contents of a view are rendered once and then rendered again only when the model’s contents change. This model works very well for views, because in practice most view content is static. SpriteKit, on the other hand, is designed explicitly for dynamic content. SpriteKit continuously updates the scene contents and renders it to ensure that animation is smooth and accurate.
More differences:
Different coordinate systems. Views are added to the views (not the the scene). Nodes are added to the scene (not the the view).
More about view's rendering cycle can be found here. More about how SpriteKit renders a scene can be found here .
So because of these differences you may run (not necessarily of course) into different problems when mixing these two. You have three solutions (I can think of):
1) Accessing current scene through self.view
inside GameViewControllerr Ugly solution IMO, but it will work:
@IBAction func someAction(sender: AnyObject) {
let skView = self.view as! SKView
if let currentScene = skView.scene as? GameScene {
currentScene.changeText()
}
}
2) Nice solution, but again this is just my opinion - Implementing custom buttons using SKSpriteNode. Just search SO about this.
3)Use third party SpriteKit buttons like SKAButton or AGSpriteButton.
Upvotes: 2