Button title does not update after userdefaults

32 Views Asked by At

Here is my UIBarButtonItem extension:

extension UIBarButtonItem {
static func button(image: UIImage, title: String, target: Any, action: Selector) -> UIBarButtonItem {
    let button = UIButton()
    button.layer.cornerRadius = 4
    button.layer.borderColor = #colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1)
    button.layer.borderWidth = 1
    button.backgroundColor = #colorLiteral(red: 0.7725490332, green: 0.7725490332, blue: 0.7725490332, alpha: 1)
    button.setImage(image, for: .normal)
    button.addTarget(target, action: action, for: .touchUpInside)
    button.setTitle(title, for: .normal)
    button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
    button.sizeToFit()
    return UIBarButtonItem(customView: button)
}

}

I'm using this button here:

enter image description here

I want to change the price everytime totalPrice updated.

override func viewDidAppear(_ animated: Bool) {
    totalPrice = viewModel.getTotalPrice() ?? 0
}

Also here is how i calculate totalPrice:

func getTotalPrice() -> Double? {
    guard let products = userDefaults.getBasketProductsDefault() else { return 0 }
    var total: Double = 0
    for product in products {
        total = total + (Double(product.totalAmount) * product.productPrice)
    }
    return total
}

When I print the totalPrice I can see, value of this parameter changes. However, it never updates the button's title. What am I doing wrong?

1

There are 1 best solutions below

4
Mozz On

You are updating the value in viewDidAppear. viewDidAppear is called every time a the view becomes visible and before any animation is configured. You need to observe the price and trigger a change when the value changes. Combine Publishers sound like a good candidate to use here. You can setup your total price as a publisher and subscribe to it in the view.

You can do it something like this:

override func viewDidLoad() {
    super.viewDidLoad()

    self.viewModel = ViewModel()
    viewModel.$totalScore.sink { score in
        self.updateScore(score)
    }
}

func updateScore(_ score: Int) {
    
}

}

class ViewModel: ObservableObject {
@Published var totalScore: Int = 0

func getScore() {
    totalScore = 2
}
}