2010-11-10 42 views
2

J'essaye de mettre en application une application d'iPhone de Twitter comme l'interface. (Faites glisser pour remplacer la vue dans une tableviewcell avec une vue personnalisée). J'utilise le UISwipeGestureRecognizer d'Apple pour reconnaître le balayage et j'obtiens l'emplacement de départ pour ce balayage en utilisant [recognizer locationInView:self.view]. Cela me donne un CGPoint et je l'utilise avec [tableView indexPathForRowAtPoint:location]. Mon problème avec ceci est, mon coup semble toujours être détecté à une rangée au-dessus ou au-dessous de la rangée réelle que j'ai balayée. Est-ce que quelqu'un a éprouvé le même problème?indexPathForRowAtPoint ne me donnera pas l'index correct

EDIT: Je devrais probablement également mentionner que j'utilise une cellule de tableview personnalisée, et sa hauteur est plus que la vue par défaut. Je ne suis pas sûr si cela fait une différence, j'utilise heightForRowIndexAtPath: pour retourner la hauteur.

Mon code est -

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
ModelObject *rowData = (ModelObject *)[tempArr objectAtIndex:indexPath.row]; 
if (rowData.isAlternateView) { 
     // Load alternateview 
    UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)]; 
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)]; 
    [cell addGestureRecognizer:recognizer]; 
    [recognizer release]; 
    return cell; 

} 
else { 
    // Load the correct uitableviewcell 
    UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)]; 
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)]; 
    [cell addGestureRecognizer:recognizer]; 
    [recognizer release]; 

    return cell; 
} 

} 


-(void) handleSwipe:(UISwipeGestureRecognizer *) recognizer 
{ 
NSLog(@"Swipe detected!"); 
CGPoint location = [recognizer locationInView:self.view]; 
NSIndexPath *selectedIndexPath = [tableView indexPathForRowAtPoint:location]; 
NSLog(@"Swipe detected at %d", selectedIndexPath.row); 
ModelObject *rowData = (ModelObject *)[modelArr objectAtIndex:selectedIndexPath.row]; 
rowData.isAlternateView = YES; 

for (int i=0; i<[tempArr count]; i++) { 
    if (i!=selectedIndexPath.row) { 
     ModelObject *rowToBeCleared = (ModelObject *) [modelArr objectAtIndex:i]; 
     if ([rowToBeCleared isAlternateView]) { 
      [rowToBeCleared setIsAlternateView:NO]; 
      [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:i inSection:0],nil] withRowAnimation:UITableViewRowAnimationLeft]; 
     } 
    } 
} 

[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:selectedIndexPath,nil] withRowAnimation:UITableViewRowAnimationRight]; 
} 
+1

Toute self.view chance = tableView! –

Répondre

10

Tout d'abord, plutôt que d'ajouter un module de reconnaissance de geste à chaque cellule, je vous suggère ajouter un seul geste de reconnaissance à la vue toute qui contient la vue de la table (ou si c'est un UITableViewController, alors ils sont la même chose).

En viewDidLoad:

UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] 
    initWithTarget:self action:@selector(handleSwipe:)]; 
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)]; 
[self.view addGestureRecognizer:recognizer]; 
[recognizer release]; 

Ensuite, dans la méthode handleSwipe:

- (void)handleSwipe:(UISwipeGestureRecognizer *) recognizer 
{ 
    //might need to check if swipe has ended (otherwise not time to handle yet) 
    if (recognizer.state != UIGestureRecognizerStateEnded) 
     return; 

    CGPoint location = [recognizer locationInView:tableView]; //not self.view 
    NSIndexPath *selectedIndexPath = [tableView indexPathForRowAtPoint:location]; 

    if (selectedIndexPath != nil) 
    { 
     //user swiped on a tableview cell 
    } 
    else 
    { 
     //user did not swipe on a tableview cell 
    } 
} 
+0

Merci! 'recognizer.state! = UIGestureRecognizerStateEnded' a fait l'affaire. Savez-vous pourquoi cela pourrait se produire cependant? –

+1

Le programme de reconnaissance déclenche la méthode pour chaque phase du mouvement (début, modification, fin, etc.). Dans votre cas, l'emplacement peut ne pas être valide jusqu'à sa fin. – Anna

+0

merci! Tu as sauvé ma journée !!! ne peut pas voter assez !!!!!!!!!!! – SpaceDog