Chandler Long
Chandler Long

Reputation: 77

Swift 4: Unrecognized selector sent to instance when calling a function inside another class

For my application, I am working without storyboards. For that reason, I am trying to keep my ViewController clutter free by storing larger functions inside another class and calling them when needed.

For some reason, when I call my functions with #Selector I get a crash stating "Unrecognized selector sent to instance".

When I store my function inside the same ViewController as the #Selector it works just fine.

The Following Code Below Works

View Controller

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(loginRegisterButton)


}

lazy var loginRegisterButton: UIButton = {
    let button = UIButton(type: .system)
    button.backgroundColor = Color.darkBlue
    button.setTitle("Register", for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitleColor(UIColor.white, for: .normal)
    button.layer.cornerRadius = 5
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)

    button.addTarget(self, action: #selector(LoginFunctions.handleLogin), for: .touchUpInside)

    return button
}()

    @objc func handleLogin() {
    print("Logging In!!!")
    }

}

What I am trying to achieve

The code below does not work

View Controller

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(loginRegisterButton)


}

lazy var loginRegisterButton: UIButton = {
    let button = UIButton(type: .system)
    button.backgroundColor = Color.darkBlue
    button.setTitle("Register", for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitleColor(UIColor.white, for: .normal)
    button.layer.cornerRadius = 5
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)

    button.addTarget(self, action: #selector(LoginFunctions.handleLogin), for: .touchUpInside)

    return button
}()

}

LoginFunctions

import Foundation
import UIKit

class LoginFunctions {

@objc func handleLogin() {
    print("Logging In!!!")
}
}

I have been trying to debug this for days with no luck. Any help would be greatly appreciated. Thanks in advance!

Upvotes: 4

Views: 5553

Answers (2)

Shehata Gamal
Shehata Gamal

Reputation: 100503

To add a target to a class it must contain the func in selector , you may try this to share method between viewControllers

extension UIViewController 
{
    @objc func handleLogin() {
         print("Logging In!!!")
    }

}

Upvotes: 2

rmaddy
rmaddy

Reputation: 318814

There's no reference to your LoginFunctions from your ViewController. And you pass self as the target to the button but self doesn't have a handleLogin method.

You need to hold and instance of LoginFunctions in your ViewController class. Then pass that reference as the target instead of self.

class ViewController: UIViewController {
    let functions = LoginFunctions()

    lazy var loginRegisterButton: UIButton = {
        let button = UIButton(type: .system)
        button.backgroundColor = Color.darkBlue
        button.setTitle("Register", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitleColor(UIColor.white, for: .normal)
        button.layer.cornerRadius = 5
        button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)

        button.addTarget(functions, action: #selector(LoginFunctions.handleLogin), for: .touchUpInside)

        return button
    }()
}

Upvotes: 6

Related Questions