Suppose that I have a custom UITableViewCell contains UIButton control. When the user presses the button it should present another view controller with the appropriate info according to which cell was chosen (to be more precise, I have an array of objects used to represent information in the UITableView and I want to transfer this info to the next view controller). The question is how can I detect button on which cell was exactly selected?
Thanks in advance.
There are many ways of doing this.. but the way of superView is no more available since iOS8. I am sharing a code which is working perfect in all iOS.
Write this selector on your cellForRow method
[cell.btnOnCell addTarget:self action:#selector(btnAction:event:) forControlEvents:UIControlEventTouchUpInside];
Now write this method
-(void)btnAction: (UIButton *)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tblView];
NSIndexPath *indexPath = [self.tblView indexPathForRowAtPoint:currentTouchPosition];
NSLog(#"%li",(long)indexPath.row);
}
Try this:
Insert below code in cellForRowAtIndexpath
[cell.yourbuttonName addTarget:self action:#selector(yourbuttonNamePressed:) forControlEvents:UIControlEventTouchDown];
paste the below code as separate method
- (void)yourbuttonNamePressed:(UIButton *)sender
{
CGPoint swipepoint = sender.center;
CGPoint rootViewPoint = [sender.superview convertPoint:swipepoint toView:self.goalsTable];
NSIndexPath *indexPath = [self.goalsTable indexPathForRowAtPoint:rootViewPoint];
}
Simple solution is that when you configure cell in CellForRowAtIndexPath there you need to set the cell.button.tag=100+indexPath.row.
-(void)btnClicked:(UIButton *)sender
{
NSIndexPath* path= [NSIndexPath indexPathForRow:sender.tag-100 inSection:0];
UITableViewCell*cell=(UITableViewCell *)[tblView cellForRowAtIndexPath:path];
}
NOTE: you need to remove addTarget and buttonClicked implementation from UITableviewcell
and in cellForRowAtIndexPath method addtarget to button and in this class implemnt buttonClicked Method.**
Related
I have an UITableViewController that contains a tableView. I have added a tap gesture recognizer to this controller and I would like the action to happen when the user clicks everywhere except for the first row of the tableView (with indexPath.row == 0).
I have seen the following related questions and answers (among others):
this one is concerned with detecting the tableView itself (therefore it will also detect its header / footer).
I has used this one (code below) before but the problem is that it computes an indexPath of (0,0) also if one clicks on the footer / header.
.
-(BOOL) gestureRecognizer:(UIGestureRecognizer *)gesture shouldReceiveTouch:(UITouch *)touch {
CGPoint buttonPosition = [touch locationInView:self.view];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
if (indexPath.row == 0) {
return NO; // will also be returned if I click on the header / footer
}
return YES;
}
Perhaps attempt to add an "invisible" UIButton over the table view cells and then upon tap use the buttons tag as your index. Like the pseudo code below:
-cellForRowAtIndexPath:index {
UIButton *button = [UIButton alloc]initWithFrame:cell.frame];
[button setTag:index.row];
[button addTarget:self action:#selector(getIndex:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview: button]
}
-(void)getIndex:(UIButton *)sender {
finalIndex = [sender tag];
}
i just know to get indexpath button inside tableviewcell like this
CGPoint center= [sender center]; CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint]; NSLog(#"%#",indexPath);
but i need know about textfield thx for helping me guys!
There is another method to get the index row!
In cellForRow do this:
textField.tag = indexPath.row;
In the textField method do this:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
NSInteger row = textField.tag;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
}
To get the indexPath of the cell in which the textfield is contained you need to do a couple of things.
Make the viewController class the delegate of the textField in the tableView's cell
Implement textFieldDidBeginEditing method of textField's delegateProtocol in your viewController's class like this
- (void)textFieldDidBeginEditing:(UITextField *)textField {
//Here you can you the same logic to find the indexPath of the cell like you use in case of a button.
}
I have UICollectionView that has two UICollectionResuabeView(Custom View) and one UICollectionViewCell. The form a single entity in UICollectionView. I put Delete button on one of UICollectionResuabeView and by pressing it want to delete the row (if i call it right).
This is the screenshot form Storyboard:
I tried getting section of it my many means, but non works. Guess I just dont have enough knowledge of how UICollectionView works. Here is some code I tried:
I know its I mess, but at least I was trying ))
I ve tried this toget indexPath, but none works.
-(IBAction)deletePressed:(UIButton* )sender{
RecipeCollectionHeaderView *contentView = (RecipeCollectionHeaderView *)[sender superview];
RecipeViewCell *cell = (RecipeViewCell *)[contentView superview];
cell = (RecipeViewCell *)[contentView superview];
// determine indexpath for a specific cell in a uicollectionview
NSIndexPath *editPath = [self.collectionView indexPathForCell:cell];
NSInteger rowIndex = editPath.row;
NSInteger secIndex = editPath.section;
// NSIndexPath *indexPath = nil;
// indexPath = [self.collectionView indexPathForItemAtPoint:[self.collectionView convertPoint:sender.center fromView:sender.superview]];
// NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
// NSSet *touches = [event allTouches];
//
// UITouch *touch = [touches anyObject];
//
// CGPoint currentTouchPosition = [touch locationInView:self.collectionView];
//
// NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint: currentTouchPosition];
NSLog(#"IndexPath CollectionView %ld", (long)rowIndex);
}
I also tried make it work like in this post, but it does not give a result:how to access from UICollectionViewCell the indexPath of the Cell in UICollectionView
Thank you all!
EDIT!
I found this works well:
-(IBAction)deletePressed:(UIButton* )sender{
[self.ordersArray removeObjectAtIndex:0];
[self.collectionView reloadData];
}
The only thing I need now is to get section of UICollectionView by UIBotton that been pressed, to delete section I want. How to do it?)
You also need to remove item from the array and UICollectionView as well.
Try to use this code.
-(void) deleteRow:(NSInteger)index {
[self.contentView performBatchUpdates:^{
[arrayForRows removeObjectAtIndex:i];
NSIndexPath *indexPath =[NSIndexPath indexPathForRow:i inSection:0];
[self.contentView deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
} completion:^(BOOL finished) {
}];
}
For cell selection use this code snippet:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//Item position that you would like to delete.
indexPath.row;
}
I have a UITableView that has a UISegmentedControl in each cell. When the value of the UISegmentedControl is changed, I want to change a value in a MYSQL database. (It's a public/private switch)
I have this in my cellForRowAtIndexPath
[cell.pubPrivSegmentedControl addTarget:self action:#selector(switchValue:) forControlEvents:UIControlEventValueChanged];
and then this is my method
-(void)switchValue:(id)sender
{
UISegmentedControl *sc = (UISegmentedControl *)sender;
NSString *status = [sc selectedSegmentIndex] ? #"Private" : #"Public";
NSLog(#"status is %#", status);
//call method to change value in database using indexPath.row of tapped UISC
}
My question is how to pass the indexPath.row value to the selector when the segmented controller is tapped. Thanks.
You can add target in this way:
[cell.pubPrivSegmentedControl addTarget:self action:#selector(switchValue:event:) forControlEvents:UIControlEventValueChanged];
And implement method :
- (void)switchValue:(id)sender event:(id)event {
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView: tableView];
NSIndexPath *indexPath = [tableView indexPathForRowAtPoint: currentTouchPosition];
}
There is UITableViewCell which contain UIButton.
In my cellForRowAtIndexPath:
cell.toCartBtn.tag = indexPath.row;
[cell.toCartBtn addTarget:self
action:#selector(toCart:) forControlEvents:UIControlEventTouchDown];
In toCart method I need to get row and section by tapped button tag. How can I do it?
See this code
- (void)toCart:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
if (indexPath)
{
...
}
}
Use this simple code if UIButton is subview in cell
- (void)toCart:(id)sender
{
UIButton *senderButton = (UIButton *)sender;
UITableViewCell *cell=(UITableViewCell*)senderButton.superView;
NSIndexPath *index = [tableView indexPathForCell:cell];
}
Create a custom UITableViewCell subclass and handle the touch in there.
Then define a delegate for your custom table view cell and when you create the cell, assign your table view data source as the delegate.
When the cell handles the touch, send a message to the delegate and then find the index path from the table view.
-(void)customTableViewCellButtonPressed:(CustomTableViewCell *)cell {
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
...
}
try this:
- (void)toCart:(id)sender {
CGPoint button1 = [sender convertPoint:CGPointZero toView:self.tblName];
NSIndexPath *index = [self.tableView indexPathForRowAtPoint:button1];
//use index variable
}
and also see for more details for your bug...
Detecting which UIButton was pressed in a UITableView
For Swift
let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to: self.tableViewItems)
let indexPath = self.tableViewItems.indexPathForRow(at: buttonPosition)
if (indexPath != nil)
{
print(indexPath?.section)
print(indexPath?.row)
}