Reputation: 2116
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
Reputation: 16022
You can use this approach:
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>
Set action/target to your view controller (or maybe table view delegate)
[ myButton addTarget:<view controller> action:@selector( buttonTapped: ) forControlEvents:UIControlEventTouchUpInside ] ;
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
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
Reputation: 69027
You don't show any code to comment on, but generally speaking you can:
define a tag
for each button which represents the table row where the button appears;
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