vgvishesh23113
vgvishesh23113

Reputation: 319

Swift | UIButton causes crash on tap

I added a button on the main screen of the app and on the tap of a button, a new viewcontroller is presented. This works completely fine in the simulator but as soon as I try in an actual iPhone, it causes the app to crash.

Also, the crash is only caused on the login button while the sign up button made the same way does work perfect

I will leave the code below

 var loginButton = UIButton()
var signUpButton = UIButton()

 loginButton.setTitle("Login", for: .normal)
    loginButton.titleLabel?.textAlignment = .center
    loginButton.backgroundColor = appGreenTheme
    loginButton.titleLabel?.textColor = .white
    loginButton.layer.cornerRadius = 20
    loginButton.titleLabel?.font = UIFont.systemFont(ofSize: 20)
    loginButton.setBackgroundImage(UIImage(named: "pinkOrangeGradientPDF"), for: .normal)
    loginButton.clipsToBounds = true


    signUpButton.setTitle("Sign Up", for: .normal)
    signUpButton.setTitleColor(.black, for: .normal)
    signUpButton.titleLabel?.textAlignment = .center
    signUpButton.backgroundColor = .white
    signUpButton.titleLabel?.textColor = .black
    signUpButton.layer.cornerRadius = 20
    signUpButton.titleLabel?.font = UIFont.systemFont(ofSize: 20)


    loginButton.addTarget(self, action: #selector(loginButtonTapped1(_:)), for: .allTouchEvents)

    signUpButton.addTarget(self, action: #selector(signUpButtonTapped1(_:)), for: .allTouchEvents)

 ///////////////////////////////////////////////////

   @objc func loginButtonTapped1(_ sender: UIButton) {
    let nav = UINavigationController(rootViewController: LoginViewController())
self.present(nav, animated: true, completion: nil)
}

@objc func signUpButtonTapped1(_ sender: UIButton) {
    let nav = UINavigationController(rootViewController: SignUpViewController())
    self.present(nav, animated: true, completion: nil)
}

I also tried with "touchUpInside" events. again it works perfectly in the simulator but not in a physical device.

Any help is welcome.

Below is the error shown in the logs

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SparkGPS.LoginView addTarget:action:forControlEvents:]: unrecognized selector sent to instance 0x13dd4c740'

Upvotes: 1

Views: 735

Answers (2)

Jeffery Thomas
Jeffery Thomas

Reputation: 42598

The answer is in the error message. Somewhere, my guess is in LoginViewController, there is a view of type LoginView. That view is calling addTarget(_:action:for:). LoginView is not subclassed from UIControl and does not have addTarget(_:action:for:). It's causing the crash.

Let me break down the parts of -[SparkGPS.LoginView addTarget:action:forControlEvents:].

  • The - at the beginning means it's an instance method and not a static or class method.

  • SparkGPS.LoginView is the module and class. A module is another word for a framework or app. In this case, it looks like you have an app named SparkGPS and a class named LoginView.

  • addTarget:action:forControlEvents: is Objective-C's name for addTarget(_:action:for:).

Finally, "selector sent to instance" means the variable call a method. Selector is a way to identify a method, and an instance is stored in a variable. For example, in your code you have loginButton.setTitle("Login", for: .normal). This could be worded as setTitle(_:for:) was sent to the instance loginButton.

Upvotes: 1

Adam Wareing
Adam Wareing

Reputation: 246

You can add a tap gesture recogniser to the button itself. It's best practice to use outlets, but this works fine and is useful for other UI components like views or labels too

let loginTapGesture = UITapGestureRecognizer(target: self,
                                                 action: #selector(loginButtonTapped1))
loginButton.addGestureRecognizer(loginTapGesture)

Upvotes: 0

Related Questions