Sara
Sara

Reputation: 33

Updating UILabel text programmatically using a function

so I am trying to update the UIlabel text using a func. I have seen few other questions like mine and I tried their method but it doesn't work. fun returns no value when used in the UIlabel. I have shown my code below.It has to be noted that when I use the function in viewdidload I can retrieve the data.

lazy var name: UILabel = {
  let lb = UILabel()
  lb.text? = getthename()
  lb.lineBreakMode = NSLineBreakMode.byWordWrapping
  lb.textColor = .mainGreen
  lb.textAlignment = .left
  lb.font = UIFont.boldSystemFont(ofSize:12.0)
  return lb
}()

func getthename() -> String {
  var wins : String = ""
  let ud = (Auth.auth().currentUser?.uid)
  self.ref = Database.database().reference()
  self.ref.child("Users").child(ud!).observeSingleEvent(of: .value, with: {(snapshot) in
    if let getData = snapshot.value as? [String:Any] {
      wins = (getData["lastName "] as? String)!
    }
  })
  return wins
}

Upvotes: 1

Views: 450

Answers (1)

Rob Barber
Rob Barber

Reputation: 504

Try replacing this line of code

lb.text? = getthename()

With lb.text = getthename()

You're currently using optional unwrapping by using the "?" symbol and it is causing that line to essentially equate to nil = getthename()

Also, as mentioned by @Larme the following code is actually asynchronous:

self.ref.child("Users").child(ud!).observeSingleEvent(of: .value, with: {(snapshot) in
    if let getData = snapshot.value as? [String:Any] {
      wins = (getData["lastName "] as? String)!
    }
  })

Rather than trying to set your label's text within the lazy variable initializer I would recommend you set it elsewhere. You can update the getthename() function to use a reference to the label to update the label's text after the call to observeSingleEvent() has returned.

So something like this

lazy var name: UILabel = {
  let lb = UILabel()
  lb.lineBreakMode = NSLineBreakMode.byWordWrapping
  lb.textColor = .mainGreen
  lb.textAlignment = .left
  lb.font = UIFont.boldSystemFont(ofSize:12.0)
  return lb
}()

Then the getthename() function can be changed to the following. You can call the function from anywhere and it will set the label for you.

func getthename() {
  var wins : String = ""
  let ud = (Auth.auth().currentUser?.uid)
  self.ref = Database.database().reference()
  self.ref.child("Users").child(ud!).observeSingleEvent(of: .value, with: { [weak self] (snapshot) in
    if let getData = snapshot.value as? [String:Any] {
      self?.name.text = (getData["lastName "] as? String)!
    }
  })
}

Please notice the [weak self] in the observeSingleEvent() closure as with any asynchronous code you need to check to make sure whether the right variables are still available.

Upvotes: 2

Related Questions