Whats wrong about the delegate and protocol?

Overview: When I click "Choose Color" button in the 1st view controller, it will direct me to the 2nd view controller to choose red or blue background color by clicking "Red" or "Blue" button. At last, the 2nd view controller will be dismissed after clicking the color button and background color will be display on the 1st view controller.

Problem: background color can not be displayed on the 1st view controller.

My code for 1st view controller:

import UIKit

protocol ChangingColor{
    func changingColor(color: UIColor)
}

class BossVC: UIViewController {
    @IBOutlet weak var redButton: UIButton!
    
    var BossDelegate: ChangingColor?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func redTapped(_ sender: UIButton) {
        BossDelegate?.changingColor(color: .red)
        dismiss(animated: true, completion: nil)
    }
    
    @IBAction func blueTapped(_ sender: UIButton) {
        BossDelegate?.changingColor(color: .blue)
        dismiss(animated: true, completion: nil)
    }
}

My code for 2nd view controller:

import UIKit

class FreelancerVC: UIViewController, ChangingColor{

    override func viewDidLoad() {
        super.viewDidLoad()
        
    }

    @IBAction func handleChooseColorTapped(_ sender: UIButton) {
        performSegue(withIdentifier: "goToBoss", sender: self)
        let bossVC = BossVC()
        bossVC.BossDelegate = self
    }
    
    func changingColor(color: UIColor) {
        
        view.backgroundColor = color
    }
}

This question is about UIKit, which is an Apple-private framework, and not a question about the Swift language and language support tools. I would suggest that you ask this over on some Apple-specfic developer site like the Apple Developer forums. You'll have a larger audience that is knowledgeable about the Apple development environment

Hello @Natalie,

I just looked through your code and maybe I can help you. If I understand it correctly, you have the FreelancerVC view controller with a button that leads to the BossVC. In the BossVC view controller, you have two buttons and once the user taps on on, the FreelancerVC should be informed and change the background accordingly.
For this architecture, you need a connection between the two instances in order to communicate. Your approach with delegation looks fine. There is just one small issue: In handleChooseColorTapped(), you set the BossDelegate property on a new instance of BossVC instead of using the one that is actually shown. So, in order to fix this, try inserting the following code in FreelancerVC:

func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
   if segue.identifier == "goToBoss" {
      if let bossVC = segue.destination as? BossVC {
         bossVC.BossDelegate = self
      }
   }
}

This function is called automatically once the segue is triggered (so after the button has been tapped) and segue.destination is a reference to the correct BossVC. The two lines let bossVC = ... can be deleted as they have no effect.

Also, I would recommend to use lowercase variable names (bossDelegate instead of BossDelegate) and to use a weak reference for bossDelegate in order to avoid reference cycles.

I hope I could help you a bit - best of luck and greetings from Germany!

1 Like

Hallo Victor,

Thanks for your detailed explain. Yes you understand the project correctly.

I tried to insert the piece of code under the function named "handleChooseColorTapped" which triggered the segue.

And yet, the background color of FreelancerVC doesn't change. I wonder if I should insert it in another place?

import UIKit

class FreelancerVC: UIViewController, ChangingColor{

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func handleChooseColorTapped(_ sender: UIButton) {
        performSegue(withIdentifier: "goToBoss", sender: self)
    }

// I insert the code here//
    func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
       if segue.identifier == "goToBoss" {
          if let bossVC = segue.destination as? BossVC {
             bossVC.bossDelegate = self
          }
       }
    }
    
    func changingColor(color: UIColor?) {
        view.backgroundColor = color
    }
    
}
Terms of Service

Privacy Policy

Cookie Policy