Q:

Set Button Title not showing on UI in Swift

What I want to achieve?
I have 2 UITableViewController : AddCardVC and ListDeckController. I want to pass selected Deck in ListDeckController to AddCardVC then updateUI on AddCardVC
My code: (I'm building on Swift 5, iOS 13)

ListDeckController.swift:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    if let addCardVC = storyboard.instantiateViewController(withIdentifier: "AddCard") as? AddCardVC {
        if let deck = allDecks?[indexPath.row] {
            addCardVC.selectedDeck = deck
        }
    }
    self.navigationController?.popViewController(animated: true)
}

AddCardVC.swift:

var selectedDeck: Deck?
    {
        didSet {
            viewWillAppear(true)
        }
    }

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if let deck = selectedDeck {
            //Update UI
            self.chooseDeckButton.setTitle(deck.name, for: .normal)
            print(chooseDeckButton.titleLabel?.text ?? "")

            self.tableView.reloadData()
        }
    }

What happend?
After I got selected Deck in AddCardVC, the console print out chooseDeckButton.titleLabel?.text = "My Deck" which is what I want. But The button title on UI is "Choose your deck"
Console image Button on UI
So, why the setButtonTitle not showing on UI in my case? 
Thank you for your time

A:

First, create a protocol for DeckDelegate 
protocol SelectedDeckDelegate {
    func didSelectDeck(selectedDeck : Deck)
}

Now in your ListDeckController.swift, implement the delegate 
var deckDelegate : SelectedDeckDelegate?

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
{ 
if let deck = allDecks?[indexPath.row] {
    deckDelegate?.didSelectDeck(selectedDeck: deck)
    self.navigationController?.popViewController(animated: true)
} else {
    print("deck is empty")
}  
}

And in your AddCardVC, when navigating to ListDeckController, assign the delegate to self
// Make AddCardVC conform to SelectedDeckDelegate

class AddCardVC : UIViewController, SelectedDeckDelegate {

   override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if let deck = selectedDeck {
            //Update UI
            self.chooseDeckButton.setTitle(deck.name, for: .normal)
            print(chooseDeckButton.titleLabel?.text ?? "")

            self.tableView.reloadData()
        }
    }

    // assign the delegate to self here

    @IBAction func selectDeckBtnAction(_ sender : Any) {
        let vc = storyboard.instantiateViewController(withIdentifier: "ListDeckController") as? ListDeckController
        vc.deckDelegate = self
        self.navigationController?.pushViewController(vc, animated: true)
    }

    // this will get called whenever selectedDeck is updated from ListDeckController
    func didSelectDeck(selectedDeck: Deck) {
        self.selectedDeck = selectedDeck
        chooseDeckButton.setTitle(selectedDeck.name , for: .normal)
    }
 }

