iosswiftuiviewcontrollerxibnib

unrecognized selector sent to instance error in view controller instantiated from a nib


I created a UIViewController called FacebookLoginView with a nib file for it. The nib's File Owner is set to FacebookLoginView. I added two buttons on it and have added the IBActions in the .swift file.

enter image description here

import UIKit
import FacebookLogin

class FacebookLoginView: UIViewController {

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

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

    // MARK: - Actions
    @IBAction func didTapCloseButton(_ sender: UIButton) {
        dismiss(animated: true, completion: nil)
    }

    @IBAction func didTapFacebookLoginButton(_ sender: UIButton) {
        print(#function)
    }

}

I instantiate this FacebookLoginView and show it from another view controller like this.

let vc = FacebookLoginView.loadFromNib()
present(vc, animated: true, completion: nil)

extension UIViewController {
    class func loadFromNib<T: UIViewController>() -> T {
        return T(nibName: String(describing: self), bundle: nil)
    }
}

When I tap on either of those buttons on the FacebookLoginView, it crashes with the follwing error.

-[UIViewController didTapFacebookLoginButton:]: unrecognized selector sent to instance 0x14d62940 2017-08-07 20:51:00.997802+0530 RandomFlyer[4010:910999] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController didTapFacebookLoginButton:]: unrecognized selector sent to instance 0x14d62940'

I removed and readded the IBAction connections but the error is still occurring.


Solution

  • I guess you have not used generics correctly where T is of type UIViewController but the iniatizer requires a concrete type. This should work instead:

    extension UIViewController {
        class func loadFromNib() -> Self {
            return self.init(nibName: String(describing: self), bundle: nil)
        }
    }