Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

indexPathForRowAtPoint returns nil only for first cell in a uitableview

I have a UIButton inside of a custom UITableViewCell that removes the cell when the button is pressed. In order to get the indexPath of the cell the button is in, I'm calling indexPathForRowAtPoint: in a method called when the button is pressed as follows:

-(void)buttonPressed:(UIButton *)sender{
    CGPoint btnPosition = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:btnPosition];

    if (indexPath != nil)
    {
    //remove the cell from the tableview. 
    }
}

This works fine if I press the button in any cell except the first cell, and also when if there is ONLY one cell in the table. However, if there are multiple cells and I press the button in the first cell, the button press is triggered and the btnPosition is found, but [self.tableView indexPathForRowAtPoint:btnPosition]; returns nil.

For example, if there are three cells, each with a button:

  1. I press the first cell button: buttonPressed is called but indexPath is nil, so nothing happens.
  2. I press the third cell button: buttonPressed is called and the cell is removed as expected.
  3. I press the first cell again: same as before, buttonPressed called but indexPath is nil.
  4. I press the second cell button: buttonPressed is called and the cell is removed as expected.
  5. I press the first cell button: This time, buttonPressed is called, indexPath is not nil and the cell is removed as expected.

I've checked that the tableView is not nil, as suggested by a related, but different, post. I've also confirmed that the point btnPosition is set to the same value (x=260, y=44.009995) both when [self.tableView indexPathForRowAtPoint:btnPosition] == nil AND when [self.tableView indexPathForRowAtPoint:btnPosition] != nil.

So aside from asking if anyone has any ideas on what could be happening here, my question is:

Under what circumstances could passing the same CGPoint to [self.tableView indexPathForRowAtPoint:btnPosition] return a different (or nil) indexPath?

I'd appreciate help with any ideas of where I might look to track this down, or to hear if anyone has encountered a similar issue.

Some additional notes that might be helpful (please excuse if I make a question asking faux-pas. I'll happily take your feedback about that as well :)

  • This tableView is part of a UITableViewController which is embedded in a UINavigationController

  • The tableView has 3 sections, 2 of which are hidden from view (0 rows, no footer, no header) while I'm presenting the section with the button cell rows as described.

  • I'm adjusting the location of the buttons during presentation by programmatically changing their horizontal constraints.

  • The heights of my customUITableViewCell, tableViewRows and UIButton are each equal to 60.0f

like image 260
riocordero Avatar asked Mar 13 '14 03:03

riocordero


2 Answers

Just try this:

fix target selector:

[button addTarget:self action:@selector(buttonPressed:event:)forControlEvents:UIControlEventTouchUpInside];


- (void)buttonPressed:(id)sender event:(id)event{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchPos = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:touchPos];
    if(indexPath != nil){
        //do operation with indexPath
    }
}
like image 98
simalone Avatar answered Sep 28 '22 21:09

simalone


I feel awful that I will get points for this, but @rmaddy's comment worked wonders for my code. I want to put this as an answer since I missed his comment the first time round and spent ages implementing a longer fix. Thanks rmaddy for the fix:

As an experiment, try using CGPointMake(5,5) instead of CGPointZero. Does that make any difference?

rmaddy then explained why it worked:

Given that you were using CGRectZero and the fact that the y coordinate of btnPosition was a strange value (44.009995 instead of 44), I suspected you may have either had an edge case or been victim to roundoff error. By choosing a point that wasn't in the absolute corner of the view, you had a better chance of avoiding roundoff issues.

rmaddy - this issue has been bugging me for 2 weeks... and you fixed it. Thank you very much. Can I donate any points on stackoverflow to you?

like image 23
Charlie Seligman Avatar answered Sep 28 '22 21:09

Charlie Seligman