Kgrover
Kgrover

Reputation: 2116

Buttons for each row UITableView

I have a custom cell in a UITableView, defined by a custom class (.h and .m files). I am able to display the cell, and change the text for each cell in the list, but my custom cell also has buttons in it (two, actually). When I click the button, I need to know which row's button has been clicked. Is there any way to get this within the custom ui cell class?

I hope what I'm requesting is clear. If not, feel free to comment and I'll try to explain as best as possible.

Upvotes: 0

Views: 1479

Answers (3)

nielsbot
nielsbot

Reputation: 16022

You can use this approach:

  1. Set an associated object value with each button. You can support this by adding a category to UIButton

    @interface UIButton (AssociatedObject)
    @property ( nonatomic, retain ) id associatedObject ;
    @end
    

    Implementation:

    @implementation UIButton (AssociatedObject)
    
    -(void)setAssociatedObject:(id)object
    {
        objc_setAssociatedObject( self, @"_associatedObject", object, OBJC_ASSOCIATION_RETAIN_NONATOMIC ) ;
    }
    
    -(id)associatedObject
    {
        return objc_getAssociatedObject( self, @"_associatedObject" ) ;
    }
    
    @end
    

    Use this like this:

    myButton.associatedObject = <some object>
    
  2. Set action/target to your view controller (or maybe table view delegate)

    [ myButton addTarget:<view controller> action:@selector( buttonTapped: ) forControlEvents:UIControlEventTouchUpInside ] ;
    
  3. In your action, look at the sender's associated object. Sender will be your UIButton

    -(void)buttonTapped:(UIButton*)sender
    {
        // retrieve object associated with the tapped button:
        id associatedObject = sender.associatedObject ;
    }
    

Upvotes: 2

Justin Paulson
Justin Paulson

Reputation: 4388

I have done this by creating a protocol for the custom cell class and then making the UIViewController that is handling the UITableView the delegate for each of the custom cells.

Then I attached the UIButton to an IBAction in the custom cell class that made a call to it's delegate with information about which cell it is or which information I needed to act on.

So I would set up a protocol with something like:

@protocol CustomCellDelegate <NSObject>

- (void) cellButtonPressed:(NSDictionary *)stuffForDelegate;

@end

Then when I implemented cellButtonPressed: in the ViewController I would use stuffForDelegate to determine which cell it was or what information I needed to act on.

The tag method is okay, but I find it tedious to deal with all of the tags flying around and I prefer using objects and protocols and delegates instead.

Upvotes: 0

sergio
sergio

Reputation: 69027

You don't show any code to comment on, but generally speaking you can:

  1. define a tag for each button which represents the table row where the button appears;

  2. when your button action method is called, you can access then the tag property of the button to know which row it was.

       - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
       {
           UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
           if (cell == nil) {
             ...
           }
           ...
           [button setTag:indexPath.row];
           ...
       }
    
    
       - (void)buttonPressedAction:(id)sender
       {
           UIButton *button = (UIButton *)sender;
           int row = button.tag;
       }
    

For a more elaborate solution, have a look at this S.O. thread.

Upvotes: 2

Related Questions