3

When I first run my app, I retrieve a number from my server and display it for my UIButton label. Think of this as a notification number displayed on a red UIButton.

When I remove a notification within the app, I want my UIButton label decrement by 1. I am able to get the decremented number from the server after I delete a notification, but I can't display this new number on the UIButton. The button always displays the number when the app is first fired.

I call makeButtonView() method after I remove a notification to update the UIButton

func makeButtonView(){
    var button = makeButton()
    view.addSubView(button)

    button.tag = 2
    if (view.viewWithTag(2) != nil) {
        view.viewWithTag(2)?.removeFromSuperview()
        var updatedButton = makeButton()
        view.addSubview(updatedButton)
    }else{
        println("No button found with tag 2")
    }


}

func makeButton() -> UIButton{
 let button = UIButton(frame: CGRectMake(50, 5, 60, 40))
 button.setBackgroundImage(UIImage(named: "redBubbleButton"), forState: .Normal)
    API.getNotificationCount(userID) {
        data, error in

        button.setTitle("\(data)", forState: UIControlState.Normal)

    }
    button.addTarget(self, action: "targetController:", forControlEvents: UIControlEvents.TouchUpInside)

    return button

}
  • I don't see the point of adding/removing the button from the view and create the button twice. Anyway what updatedNotificationButton is? var updatedButton = makeButton() view.addSubview(updatedNotificationButton) – agy Jul 24 '15 at 18:08
  • I did this because the label doesn't reset to the new number. It's always the same number. I thought I needed to kill the button and recreate it, but that didn't help either. I fixed the code you pointed out. – Kleinfeltersville Jul 24 '15 at 18:46

6 Answers6

6

Use this code for Swift 4 or 5

button.setTitle("Click Me", for: .normal)
AtulParmar
  • 4,358
  • 1
  • 24
  • 45
2

I need more information to give you a proper code. But this approach should work:

lazy var button : UIButton = {
    let button = UIButton(frame: CGRectMake(50, 5, 60, 40))
    button.setBackgroundImage(UIImage(named: "redBubbleButton"), forState: .Normal)
    button.addTarget(self, action: "targetController:", forControlEvents: UIControlEvents.TouchUpInside)

    return button
    }()

func makeButtonView(){
    // This should be called just once!!
    // Likely you should call this method from viewDidLoad()
    self.view.addSubview(button)
}

func updateButton(){
    API.getNotificationCount(userID) {
        data, error in
        // be sure this is call in the main thread!!
        button.setTitle("\(data)", forState: UIControlState.Normal)
    }
}
agy
  • 2,804
  • 2
  • 15
  • 22
  • It didn't work. It just works as it was before. The button label number didn't decrement. But I can see the number returned from the server after I delete a notification. – Kleinfeltersville Jul 24 '15 at 19:25
  • Just so you know I delete the notification in a different page. Then I close the notification page. The button and notifications are not on the same storyboard. – Kleinfeltersville Jul 24 '15 at 19:38
  • Storyboard? Sorry, but that doesn't make any sense. Are you creating your button using storyboard or programatically? – agy Jul 24 '15 at 19:53
  • Red notifications button and Notifications view--where I delete a notification-- are two different parts of the same app. I tap on notifications button when I run the app frst, notifications view comes up. I delete a notification, close the page and I see the red button label didn't change. – Kleinfeltersville Jul 24 '15 at 19:58
  • Yes, I am creating the button programatically. Sorry, I should have said storyboard, they are not on the same view. – Kleinfeltersville Jul 24 '15 at 20:00
  • Where updateButton() is called? Could you please show the code of getNotificationCount(userId)? Are you sure data has the updated valued? – agy Jul 24 '15 at 20:04
  • `func updateButton(){ API.getNotificationCount(userID) { data, error in /*I see data is data is the right number*/ self.button.setTitle("\(data)", forState: UIControlState.Normal) } }` – Kleinfeltersville Jul 24 '15 at 20:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/84223/discussion-between-agy-and-kleinfeltersville). – agy Jul 24 '15 at 20:32
1

There have been some updates since Swift 4. This works for me:

self.button.setTitle("Button Title", for: UIControl.State.init(rawValue: 0))

Replace button with your IBOutlet name. You can also use a variable or array in place of the quoted text.

Eugene
  • 11
  • 1
0

It's fairly simple ...

import UIKit

class ViewController: UIViewController {

    @IBOutlet var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        button.setTitle("hello world", forState: UIControlState.Normal)
    }
}

I believe if you set the state to normal, the value will propagate by default to other states so long as you haven't explicitly set a title for those states.

Said differently, if you set it for normal, it should also display this title when the button enters additional states

UIControlState.allZeros
UIControlState.Application
UIControlState.Disabled
UIControlState.Highlighted
UIControlState.Reserved
UIControlState.Selected

Lastly, here's Apple's documentation in case you have other questions.

ABC
  • 41
  • 3
0

Since your API call should be running on a background thread you need to dispatch your UI update back to the main thread like this:

DispatchQueue.main.async {
      button.setTitle(“new value”, forState: .normal)
  }
zfetters
  • 447
  • 2
  • 11
0

After setting the title, just a simple redraw of the button will do:

button.setNeedsDisplay();