identifying Button selection of each row in Tableview? - iphone

(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(230.0f, 4.0f, 60.0f, 36.0f);
[btn setTitle:#"OK" forState:UIControlStateNormal];
[btn setTitle:#"OK" forState:UIControlStateSelected];
[btn addTarget:self action:#selector(onClickRename:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:btn];
return cell;
}
but if the user selects the button on particular row, i can change that image through onClickRename...but can i get inwhich row's image has been touched through
(void)tableView:(UITableView )tableView didSelectRowAtIndexPath:(NSIndexPath)indexPath ?

you could do something like
[btn setTag:[indexPath] row]
in your cell setup, and then
- (void) onClickRename:(id)sender {
int row = sender.tag;
}
you'd know which table row was hit.

Apple uses the following technique in their Accessory sample code:
- (void)checkButtonTapped:(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];
if (indexPath != nil)
{
// do what you want with the item at indexPath
}
}

In Swift, you can set a tag for each button
Also, set each index value as its tag, we get to know which button is clicked at which row.
to set tag, in cellForAtIndexPath
cell.button.tag = indexPath.row
in button Action
#IBAction func anAction(_sender : AnyObject){
let tappedButton = sender.tag // gives the row and button
}

Related

Detecting which button is clicked in UITableview and changing button image

I'm using three tables in my view and seprating them each other using a tag. In my second table view i made a cutom uitableview and adding labels and buttons inside them .
this is the button which i wrote inside the cellforrowatindexpath
followingButton = [UIButton buttonWithType:UIButtonTypeCustom];
[followingButton addTarget:self action:#selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside];
[followingButton setImage:[UIImage imageNamed:#"following12.png"] forState:UIControlStateNormal];
following.tag=indexpath.row;
[followingButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0);
[cell.contentView addSubview:followingButton];
======
-(void)followingButtonpressed:(id)sender
{
UIView *contentView1 = (UIView *)[sender superview];
UITableViewCell *cell1= (UITableViewCell *)[contentView1 superview];
NSIndexPath *indexPath1 = [followingTable indexPathForCell:cell1];
[sender tag];
NSLog(#"sender tag --%d",[sender tag]);
// UIButton *button = (UIButton *)sender;
// UITableViewCell *cell = (UITableViewCell*)[button superview];
UIButton *tempButtom = (UIButton *)[cell1 viewWithTag:[sender tag]];
[tempButtom setImage:[UIImage imageNamed:#"following_off12.png"]
forState:UIControlStateNormal];
}
But its crashing and i was not able to change the image of selected button , please help
Use this to detect which button has been pressed
UIView *senderButton = (UIView*) sender;
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: (UITableViewCell*)[[senderButton superview]superview]];
Give Tag to each UIButton and write following code for detect which button is pressed
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
// Get the UITableViewCell which is the superview of the UITableViewCellContentView which is the superview of the UIButton
(UITableViewCell*)cell = [[button superview] superview];
int row = [myTable indexPathForCell:cell].row;
// Here **row** give you tad of specific UIButton that you tapped
if (row == yourTag )
{
// write code for action
}
}
Or you can set tag for cell each time, but not UIButton. Your action will look then:
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
int row = [button superview].tag;
// Here **row** give you tad of specific UIButton that you tapped
if (row == yourTag )
{
// write code for action
}
}

Selecting UITableViewCell AccessoryView, separate from selecting row

I have a UITableview that I'm displaying some tasks and each row has a checkbox to mark tasks complete or not.
I'm looking to toggle the checkmark when the user taps on the checkbox, and switch to a detailed view when the user taps on the row. The latter is easy, just by using
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
However, I wanted to separate the selection areas, toggling only the checkbox when the accessoryview is selected, and going into detailed view only when the rest of the cell is selected. If I add a UIbutton inside the accessoryview, the user would be selecting the row AND the UIButton when they only wanted to hit the checkbox, right?
Also, what if the user was just scrolling through the tableview by dragging along the accessoryview? Wouldn't this trigger an action on the UIButton on TouchUp?
Anyone have any ideas on how to do this? Thanks for your time!
How about managing accessory taps inside this delegate method:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
EDIT:
You can do something like this for custom accessoryView that responds to accessoryButtonTappedForRowWithIndexPath: method.
In cellForRowAtIndexPath: Method -
BOOL checked = [[item objectForKey:#"checked"] boolValue];
UIImage *image = (checked) ? [UIImage imageNamed:#"checked.png"] : [UIImage imageNamed:#"unchecked.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal];
[button addTarget:self action:#selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
- (void)checkButtonTapped:(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];
if (indexPath != nil)
{
[self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
}
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSMutableDictionary *item = [dataArray objectAtIndex:indexPath.row];
BOOL checked = [[item objectForKey:#"checked"] boolValue];
[item setObject:[NSNumber numberWithBool:!checked] forKey:#"checked"];
UITableViewCell *cell = [item objectForKey:#"cell"];
UIButton *button = (UIButton *)cell.accessoryView;
UIImage *newImage = (checked) ? [UIImage imageNamed:#"unchecked.png"] : [UIImage imageNamed:#"checked.png"];
[button setBackgroundImage:newImage forState:UIControlStateNormal];
}

can icon on UITableViewAccessory replace?

i have a table view, in one condition i want to use an accessory using UITableViewCellAccessoryDetailDisclosureButton, but i want to change that icon with my icon, can i do it??
yes ....you can do it easily by adding custom button...
Create the Custom button,
Setting the image of button
Add this button to accessoryView
Set the method for the button
I am providing you some help with the Code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell =(Custom *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[Custom alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
[cell setBackgroundColor:[UIColor clearColor]];
menuTable.separatorColor =[UIColor clearColor];
}
UIImage *image = [UIImage imageNamed:#"ButtonClickOrder.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.frame = frame; // match the button's size with the image size
//[button setBackgroundImage:image forState:UIControlStateNormal];
[button setImage:image forState:UIControlStateNormal];
// set the button's target to this table view controller so we can interpret touch events and map that to a NSIndexSet
[button addTarget:self action:#selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
return cell;
}
//These are the methods which are called with the AccessoryView is Clicked
- (void)checkButtonTapped:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:menuTable];
NSIndexPath *indexPath = [menuTable indexPathForRowAtPoint: currentTouchPosition];
NSLog(#"Section:%d",indexPath.section);
NSLog(#"Index:%d",indexPath.row);
if (indexPath != nil)
{
[ self tableView: menuTable accessoryButtonTappedForRowWithIndexPath: indexPath];
}
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%d",indexPath.section);
}
Hope this will surely work for u....

help on button.tag = indexPath.row

I have this code on my cellForRowAtindexPath, with a custom cell and a button on the each cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"tblCellView";
TableCellView *cell = (TableCellView *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
Alarms *alarma = (Alarms *)[alarmsArray objectAtIndex: indexPath.row];
if (!cell) {
[[NSBundle mainBundle] loadNibNamed:#"TableCellView" owner:self options:nil];
cell = tblCell;
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(-7, 4, 30, 33)];
[button addTarget:self action:#selector(favButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:1];
[cell.contentView addSubview:button];
[button release];
}
// Set up the cell.
[cell setLabelText: [alarma nombreAlarma]];
UIButton *button = (UIButton *)[cell viewWithTag:1];
button.tag = indexPath.row;
return cell;
}
My problem is that when I click on the button, I got random results, as soon as I move on the table and cells are reusing I got different indexes that are not equal to label tex for the cell in question.
-(IBAction)favButtonAction: (id)sender
{
UIButton *button = (UIButton *)sender;
Alarms *alarma = (Alarms *)[alarmsArray objectAtIndex: button.tag];
NSLog(#"labelText: %#",[alarma nombreAlarma]);
}
for example, the first cell always is ok but the last cell is equal to first objectAtIndex (maybe button.tag is equal to 0 when it must be 14?)
Ok I found a solution, is a different approach but it works :
[button addTarget:self action:#selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
and then on the button handler:
- (void)checkButtonTapped:(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];
if (indexPath != nil)
{
...
}
}
more info here Detecting which UIButton was pressed in a UITableView
Don't put tag value for button inside cell.
This is my button inside the content view of my cell. Note: button should be subview of Contentview.
[cell1.YourButton addTarget:self action:#selector(OnClickCategory:) forControlEvents:UIControlEventTouchUpInside];
Action for my button
- (void) OnClickCategory:(id) sender {
//NSIndexPath *indexPath =(NSIndexPath *)[sender tag];
UIView *senderButton = (UIView*) sender;
NSIndexPath *indexPath = [CategoryTable indexPathForCell: (UITableViewCell*)[[senderButton superview]superview]];
NSLog(#"%d",indexPath.row);
}
This works for me.

UITableView Cell - get IndexPath.row from button?

I currently have a button defined in a cell and a method to track its UITouchDown action as shown:
- (void) clickedCallSign:(id)sender {
int index = [sender tag];
NSLog(#"event triggered %#",index);
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
//Callsign button
UIButton *button;
CGRect rect = CGRectMake(TEXT_OFFSET_X, BORDER_WIDTH, LABEL_WIDTH, LABEL_HEIGHT);
button = [[UIButton alloc] initWithFrame:rect];
cell.tag=[indexPath row];
button.tag=[indexPath row];
[button addTarget:self action:#selector(clickedCallSign:) forControlEvents:UIControlEventTouchDown];
[button setBackgroundColor:[UIColor redColor]];
[button setTitle:#"hello" forState:UIControlStateNormal];
[cell.contentView addSubview:button];
[button release];
}
However when I click a cell in the simulator, the console debug message is: "event triggered (null)" and my app crashes shortly after.
How can I correctly get the indexPath.row value into my clickedCallSign method?
First off, index is an int, so your NSLog needs to look like this (note the %d):
NSLog(#"event triggered %d", index);
(It's possible that this leads to a crash, but it's also likely that something else entirely is going that causes the instability.)
Tag is good until you haven't both sections and rows. Try another way to get index path:
- (void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCell*)cell forRowAtIndexPath:(NSIndexPath*)indexPath {
//...
[button addTarget:self action:#selector(clickedCallSign:withEvent:) forControlEvents:UIControlEventTouchDown];
//...
}
// Get the index path of the cell, where the button was pressed
- (NSIndexPath*)indexPathForEvent:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
return [self.tableView indexPathForRowAtPoint:currentTouchPosition];
}
- (IBAction)clickedCallSign:(id)sender withEvent:(UIEvent*)event
{
NSIndexPath* buttonIndexPath = [self indexPathForEvent:event];
}
If you don't want to use the tag field, have the button invoke this method:
- (void)tapAccessoryButton:(UIButton *)sender
{
UIView *parentView = sender.superview;
// the loop should take care of any changes in the view heirarchy, whether from
// changes we make or apple makes.
while (![parentView.class isSubclassOfClass:UITableViewCell.class])
parentView = parentView.superview;
if ([parentView.class isSubclassOfClass:UITableViewCell.class]) {
UITableViewCell *cell = (UITableViewCell *) parentView;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
[self tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
}
}