user7804097
user7804097

Reputation: 308

UITapGestureRecognizer Crashes App..?

I am using image views to display users' friends lists. The user should be able to tap on a friend's icon and be taken to another screen. The code I've written works perfectly on the Xcode simulator. However, when running on a device, the app crashes every single time as soon as I tap an icon.

I really am unsure where to even start debugging this, even after tons of google-ing. Any advice/ help is appreciated.

I have read that my specific error potentially has something to do with memory allocation(?) but still unsure where to start/ what to do. When I check my device logs, the exception type shows this: Exception Type: EXC_BAD_ACCESS (SIGSEGV). I've followed tutorials on finding zombies and it did not help. Thank you.

I'm not really sure what code to post, but since you'll probably want to make sure I am setting up the icons correctly: (i've deleted some code to keep it simple as possible; this is running in a loop to create x amount of icons)

let iv = UIImageView()
iv.translatesAutoresizingMaskIntoConstraints = false
iv.image = image!
iv.tag = j
iv.isUserInteractionEnabled = true

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.iconTapped))
iv.isUserInteractionEnabled = true
iv.addGestureRecognizer(tapGestureRecognizer)

iconTapped function:

func iconTapped(gestureRecognizer: UITapGestureRecognizer, _ sender: AnyObject) {
    print("TAPPED NUMBER: \(gestureRecognizer.view?.tag)")

    tappedIcon = CurrentSixFriendsList[(gestureRecognizer.view?.tag)!]

    let nextVC = ConfirmOpponentViewController()
    nextVC.chosenOpponent = tappedIcon
    navigationController?.pushViewController(nextVC, animated: true)
}

UPDATE: I've commented out all code on nextVC and all code in iconTapped except for a print statement. The app still crashes on device only when I tap any friend icon.

  func iconTapped(gestureRecognizer: UITapGestureRecognizer, _ sender: AnyObject) {

    print("tapped")

}

SECOND UPDATE: so i commented out all the code for rendering the image views and I hardcoded an image view. (just one image view) with a static image from my project. the image view displays and the app crashes even when i tap on this imageView. why is it acting so strange!? i'm going crazy... I added this code in VDL just to experiment:

 let iv = UIImageView()
    iv.isUserInteractionEnabled = true
    iv.translatesAutoresizingMaskIntoConstraints = false
    iv.image = #imageLiteral(resourceName: "settings icon")
    view.addSubview(iv)
    iv.widthAnchor.constraint(equalToConstant: 100).isActive = true
    iv.heightAnchor.constraint(equalToConstant: 100).isActive = true
    iv.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    iv.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(iconTapped))
    iv.addGestureRecognizer(tapGestureRecognizer)

Upvotes: 4

Views: 1928

Answers (3)

Ranjith
Ranjith

Reputation: 493

Replace your tap gesture code & From swift 3.x you need to use #selector

let tapGesture = UITapGestureRecognizer.init(target: self, action: #selector(dismissKeyboard))
self.view.addGestureRecognizer(tapGesture)


@objc func dismissKeyboard(gesture: UITapGestureRecognizer) {
    view.endEditing(true)
}

Upvotes: 0

aksh1t
aksh1t

Reputation: 5448

Finally, found out why it was crashing.

Your tapped function:

func iconTapped(gestureRecognizer: UITapGestureRecognizer, _ sender: AnyObject) {
    print("tapped")
}

should be like this:

func iconTapped(gesture: UITapGestureRecognizer) {
    // To get the sender's tag, do this:
    print(gesture.view.tag)
}

Also adjust the #selector to the right function.

When setting a selector to UITapGestureRecognizer, the recognizer object will call the selector with only the sender, and you can not add another argument to that function.

So, the root cause of the crash is because you are trying to fit a method with one argument (which is what the gesture sends out) into a method with two arguments. This crash was very interesting because it worked all right on the simulator but only crashed in an actual device. I guess it was because the simulator and the device handle functions with extra parameters differently? (simulator ignores it vs. device crashes). If you find anything deeper as to why exactly this was happening, I would love to know.

Upvotes: 3

Arnav
Arnav

Reputation: 688

Most probly your CurrentSixFriendsList doesnot have value of gestureRecognizer.view?.tag)!.But a breakpoint before this line

tappedIcon = CurrentSixFriendsList[(gestureRecognizer.view?.tag)!]

Even then if you dont get an error then install crashlytics.This is a tool which will tell your crash issue.

Upvotes: 0

Related Questions