Search code examples
iosswiftdelegatesprotocolsxib

Protocol Delegate between XIB and View Controller


So I have XIB View and View Controller. I want when a button in my XIB clicked (didTapTryAgain Button), the called a function from my view controller. Then I tried to create a protocol and delegate for the class. But it still won't called my function. Here's my XIB view class:

import UIKit

protocol ErrorMessageDelegate {
    func refresh(_sender: AnyObject)
}

class ErrorMessage: UIView {
    @IBOutlet weak var imageViewError: UIImageView!
    @IBOutlet weak var labelError: UILabel!
    @IBOutlet weak var buttonTryAgain: UIButton!
    static weak var shared: ErrorMessage?
    var delegate: ErrorMessageDelegate?
    static var message: String?

    override func awakeFromNib() {
        ErrorMessage.shared = self
        labelError.text = ErrorMessage.message
    }

    @IBAction func didTapTryAgain(_ sender: UIButton) {
        delegate?.refresh(_sender: buttonTryAgain)
    }
}

And here's my View Controller class:

import Foundation

class BaseViewController: UIViewController, ErrorMessageDelegate {

    func refresh(_sender: AnyObject) {
        print("I hope my function work here")
    }

    var uiView =  UIView();

    override func viewDidLoad() {
        super.viewDidLoad()
        ErrorMessage.shared?.delegate = self
    }

    func getErrorMessage(message:String) {
        super.viewDidLoad()
        Dialog.dismiss()
        ErrorMessage.message = message
        guard let viewErrorMessage = Bundle.main.loadNibNamed("ErrorMessage", owner: self, options: nil)?.first as? ErrorMessage else { return}
        self.view.addSubview(viewErrorMessage)
    }
}

I'm following this answer for my code, and it still not working. Is anyone know how to do it? Thank you!


Solution

  • Your problem is that you set the delegate for a shared instance here

    ErrorMessage.shared?.delegate = self / here shared?. is nil
    

    but here

    guard let viewErrorMessage = Bundle.main.loadNibNamed("ErrorMessage", owner: self, options: nil)?.first as? ErrorMessage else { return}
    self.view.addSubview(viewErrorMessage)
    

    you create a separate instance and add it

    You need

    var viewErrorMessage:ErrorMessage! // add to the vc
    

    viewErrorMessage = Bundle.main.loadNibNamed("ErrorMessage", owner: self, options: nil)?.first as! ErrorMessage 
    viewErrorMessage.delegate = self
    self.view.addSubview(viewErrorMessage)
    

    Also completely git rid of

    static weak var shared: ErrorMessage?