Reputation: 45961
I'm developing an iOS 4 application with latest SDK and XCode 4.2.
I have a UITableView
with sections and with custom UITableViewCell
. Every cell has a UIButton and all of these buttons has the same target for UIControlEventTouchUpInside
.
This is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* cellIdentifier = @"CalendarCell";
CalendarEventCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CalendarEventCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if ([currentObject isKindOfClass:[CalendarEventCell class]])
{
cell = (CalendarEventCell *)currentObject;
[cell.addToCalendarButton addTarget:self action:@selector(addEventToiCal) forControlEvents:UIControlEventTouchUpInside];
break;
}
}
}
...
}
When user touch inside that button, how can I know on which section and row was the cell that has been clicked?
Upvotes: 3
Views: 10712
Reputation: 447
Assign Tag value to button like that in cellForRowAtIndexPath
method
cell.addToCalendarButton.tag=indexPath.row
When you add method to button also send the sender so assign method to button like that.
[cell.addToCalendarButton addTarget:self action:@selector(addEventToiCal:)forControlEvents:UIControlEventTouchUpInside];
In your method read the relevant row like that
-(IBAction)addEventToiCal:(id)sender { NSLog("current row is %d",[sender tag]); }
If you want to now about the section then indexPath do such thing then
- (void)addEventToiCal:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
NsLog("value of indePath.section %d ,indexPath.row %d",indexPath.section,indexPath.row);
}
Assign your method at cellforRowAtIndexPath Like that.
[cell.addToCalendarButton addTarget:self action:@selector(addEventToiCal:event:)forControlEvents:UIControlEventTouchUpInside];
Upvotes: 2
Reputation: 20564
BNRXIBCell is an excellent solution, for iOS 5 and above. It's a UITableViewCell subclass, intended to be subclassed, to forward action messages from cell subviews to a controller.
Upvotes: 0
Reputation: 15788
Place a tag on the button. For example:
CalendarEventCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CalendarEventCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if ([currentObject isKindOfClass:[CalendarEventCell class]])
{
cell = (CalendarEventCell *)currentObject;
[cell.addToCalendarButton addTarget:self action:@selector(addEventToiCal) forControlEvents:UIControlEventTouchUpInside];
break;
}
}
}
cell.addToCalendarButton.tag = ((indexPath.section & 0xFFFF) << 16) |
(indexPath.row & 0xFFFF);
You will need to change your selector to @selector(addEventToiCal:)
and update the method to -(void) addEventToiCal:(UIButton *)sender
.
You can then add something like the following to -addEventToiCal:
if (!([sender isKindOfClass:[UIButton class]]))
return;
NSUInteger section = ((sender.tag >> 16) & 0xFFFF);
NSUInteger row = (sender.tag & 0xFFFF);
NSLog(@"Button in section %i on row %i was pressed.", section, row);
Upvotes: 6
Reputation: 16193
Set button's target to a method in the cell instead of setting the target to the controller itself, create a delegate protocol for the cell with a method like tappedButton:(UIButton *)button inCell:(UITableViewCell *)cell
and set the controller as cell's delegate. In the target method call that delegate method.
Then in controller's delegate method implementation you can find out cell's NSIndexPath
by calling UITableView
's tableView:indexPathForCell:
.
Upvotes: 3