1

ok so first off I have an achievement Variable that is defined from a struct like so:

struct Achieve {

var node: SKSpriteNode?
var aName:String = ""
var aDes:String = ""
var aImage: String = "" {
    didSet {
        node?.texture = SKTexture(imageNamed: aImage)
    }
}
var aAmount:Int = 0
var aRequired:Int = 0
var aStage:Int = 0

}

var Ach1 = Achieve(node: nil, aName: "Player", aDes: "Games Played", aImage: "locked", aAmount: 0, aRequired: 10, aStage: 1)

My problem is when I try and change the number of the aAmount property it isn't displayed on the SKLabel that displays the amount it just stays at 0 my sklabel is defined in a function like below:

func generateLabels(location: CGPoint, page:SKSpriteNode, text: String) -> SKLabelNode {

        let node = SKLabelNode()
        node.fontColor = UIColor.whiteColor()
        node.fontName = "Helvetica"
        node.position = location
        node.fontSize = 15
        node.text = text
        page.addChild(node)
        return node
}

func menu() {

_ = generateLabels(CGPointMake(0, -285), page:page1ScrollView, text: "\(Ach1.aAmount) / \(Ach1.aRequired)") 

}

It seems to work if I make changes to aAmount when I stop running it and then change it and then run the game again. it also seems to make changes to the aAmount property during gameplay but it doesn't seem to update the label for some reason during the gameplay. Can someone please tell me why it won't update?

Also i'm updating the aAmount property like so:

 Ach1.aAmount += 1
 print("\(Ach1.Amount)")
Astrum
  • 375
  • 6
  • 21

3 Answers3

3

If I read your code, there isn't any part where you update your SKLabelNode.

If you call the function :

func menu() {
   _ = generateLabels(CGPointMake(0, -285), page:page1ScrollView, text: "\(Ach1.aAmount) / \(Ach1.aRequired)") 
}

for example to didMoveToView, it generate a label with your aAmount value when you call your scene (so 1 time only as didMoveToView works).

Instead, assuming that you call this menu function many times, it generate everytime a new label but there is no code written from you where you remove the previous label or labels added in past (see page.addChild(node)) and I don't understand why you want to return a label from your function if you don't use it, in fact you assign your result to _. Also you don't explain what is "page1ScrollView", are you using a scrollview?

Anyway, the best mode to update your label is simply to create 1 time only (for example on didMoveToView) and, everytime you want to update it, doing:

myNodeLabel.text = "\(Ach1.aAmount) / \(Ach1.aRequired)"

instead of re-create it everytime. I hope this helps to understand the dynamics that prevent your label to upgrade.

Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
3

In your Achieve struct, add a property called label:

var label: SKLabelNode?

And change the aAmount property to look something like this:

var aAmount: Int = 0 {
    didSet {
        label?.text = "\(aAmount) / \(aRequired)"
    }
}

Now when you generate the labels, replace this:

_ = generateLabels(CGPointMake(0, -285), page:page1ScrollView, 
    text: "\(Ach1.aAmount) / \(Ach1.aRequired)")

with this

var label = _ = generateLabels(CGPointMake(0, -285), page:page1ScrollView, 
    text: "\(Ach1.aAmount) / \(Ach1.aRequired)")
Ach1.label = label

Now when you change the aAmount property of Ach1, the label's text should change as well.

Suggestions:

Judging from this and your last question about sprite node images not updating, I think your programming skills are not mature enough. In the long term, you should learn the basics first. Try playing around with UIKit and read more others' code. See how other people do things. You will definitely learn a lot. In the short term though, you shouldn't make each of all these properties binds to a node. That will make Achieve too dependent. What you should do is make Achieve a subclass of SKSpriteNode and add those other sprite nodes and label nodes as sub nodes of the Achieve node.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • 1
    Your suggestion about `var label = _ = generateLabels..` don't solve the `page.addChild(node)` inside the function. There is a new label added to the page everytime the OP call his menu function and you give this new reference to a global var. In other words, there will be many labels added to the same position to the page plus your Ach1.label. – Alessandro Ornano Aug 27 '16 at 08:43
  • @AlessandroOrnano how do you know that OP will call `menu` a second time? – Sweeper Aug 27 '16 at 08:45
  • 1
    For the same reason you take for sure that OP will call menu only one time, It is not specified in the OP question, especially if you call a function with a plural name like "generateLabels" – Alessandro Ornano Aug 27 '16 at 08:56
  • This worked thanks. I am currently still learning and I may have bitten off more than i can chew with this game project idea i have but none the less i will soldier on. As for your suggestion to subclass everything i wouldn't have a clue on how to structure that. I sort of understand how class inheritance works but i always have a problem with how i would lay it out in my head and it never seems to translate into the project properly because there is always something i thought i could do but really couldn't and therefore I get frustrated with it. Thanks again for your patience and help. – Astrum Aug 29 '16 at 06:21
1

You have to reassign the text of the SKLabel. So when you call the function to change the number (or whatever it is), also run the code to make the label what you want it to be. My guess as to why it only works sometimes is that sometimes you call it in the update (or somewhere else that gets called repeatedly) and sometimes you call it somewhere like didMoveToView (only called once, so label doesn't get updated because of the way your code is).

Just whenever you update aAmount, add this code after it:

label.text = "\(aAmount)"
Nik
  • 1,664
  • 2
  • 14
  • 27
  • so how would i go about reassigning the text of the SKlabel if it is defined in a function? because I am using the update method to constantly change the aAmount. A code example would be nice. – Astrum Aug 27 '16 at 03:37