Search code examples
swiftuitableviewcustom-cell

App crashes when cell button is clicked


I'm trying to make my app have an up vote / down vote system sorta like reddit, which means each cell in my table had to react differently when the buttons are clicked to only alter their own data. I create a custom cell class and set everything up accordingly, but for some reason when I run my app it crashes anytime you hit the buttons in the cells.

Here's my code (I tried to edit out any unnecessary parts, but let me know if you'd like to see the whole thing):

import UIKit
import Firebase
import FirebaseDatabase

class FindPartiesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    // where we will store all the parties
    var parties = [party]()

    @IBOutlet weak var partyTable: UITableView!

    var refreshControl = UIRefreshControl()

    override func viewDidLoad() {
        super.viewDidLoad()

        partyTable.delegate = self
        partyTable.dataSource = self       
    }



    // creates the number of cells in the table
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return parties.count    

    // define all the cells
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        // Make table cells the show the party
        let cell = partyTable.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell

       cell.nameLabel.text = parties[indexPath.row].name

       cell.LocationLabel.text = parties[indexPath.row].location

       cell.totalVotesLabel.text = (String(parties[indexPath.row].upVotes - parties[indexPath.row].downVotes))

       cell.upVoteButton.tag = indexPath.row
       cell.upVoteButton.addTarget(self, action: Selector(("upVoteAction")), for: .touchUpInside)
       cell.downVoteButton.tag = indexPath.row
       cell.downVoteButton.addTarget(self, action: Selector(("downVoteAction")), for: .touchUpInside)



        return cell
    }

    @IBAction func upVoteAction(sender: UIButton){

       print("+1")
       parties[sender.tag].upVotes = parties[sender.tag].upVotes + 1
    }

}

(UPDATE) My error message:

2016-11-10 13:35:20.371 Lit[16625:2721786] -[Lit.FindPartiesViewController upVoteAction]: unrecognized selector sent to instance 0x7fc40b420240
2016-11-10 13:35:20.375 Lit[16625:2721786] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Lit.FindPartiesViewController upVoteAction]: unrecognized selector sent to instance 0x7fc40b420240'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001093ef34b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x0000000108e5021e objc_exception_throw + 48
    2   CoreFoundation                      0x000000010945ef34 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    3   CoreFoundation                      0x0000000109374c15 ___forwarding___ + 1013
    4   CoreFoundation                      0x0000000109374798 _CF_forwarding_prep_0 + 120
    5   UIKit                               0x0000000109814b88 -[UIApplication sendAction:to:from:forEvent:] + 83
    6   UIKit                               0x000000010999a2b2 -[UIControl sendAction:to:forEvent:] + 67
    7   UIKit                               0x000000010999a5cb -[UIControl _sendActionsForEvents:withEvent:] + 444
    8   UIKit                               0x00000001099994c7 -[UIControl touchesEnded:withEvent:] + 668
    9   UIKit                               0x0000000109d4b1dc _UIGestureEnvironmentSortAndSendDelayedTouches + 5645
    10  UIKit                               0x0000000109d45ea3 _UIGestureEnvironmentUpdate + 1472
    11  UIKit                               0x0000000109d4589b -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 521
    12  UIKit                               0x0000000109d44a7e -[UIGestureEnvironment _updateGesturesForEvent:window:] + 286
    13  UIKit                               0x00000001098837ad -[UIWindow sendEvent:] + 3989
    14  UIKit                               0x0000000109830a33 -[UIApplication sendEvent:] + 371
    15  UIKit                               0x000000010a022b6d __dispatchPreprocessedEventFromEventQueue + 3248
    16  UIKit                               0x000000010a01b817 __handleEventQueue + 4879
    17  CoreFoundation                      0x0000000109394311 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    18  CoreFoundation                      0x000000010937959c __CFRunLoopDoSources0 + 556
    19  CoreFoundation                      0x0000000109378a86 __CFRunLoopRun + 918
    20  CoreFoundation                      0x0000000109378494 CFRunLoopRunSpecific + 420
    21  GraphicsServices                    0x000000010cd78a6f GSEventRunModal + 161
    22  UIKit                               0x0000000109812f34 UIApplicationMain + 159
    23  Lit                                 0x0000000106fda27f main + 111
    24  libdyld.dylib                       0x000000010ba3668d start + 1
    25  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

Solution

  • Selector("upVoteAction")
    

    and

    func upVoteAction(sender: UIButton)
    

    are not the same, so it's not finding that method at all. You need to add change the former to

    Selector("upVoteAction:")
    

    because your actual method has a parameter.

    edit: as per @rmaddy's comment, the swift 3 way would be something like :

    #selector(upVoteAction(sender:))