J'ai un contrôleur de table qui affiche une rangée de cellules. Chaque cellule a 3 boutons. J'ai numéroté les étiquettes pour chaque cellule pour être 1,2,3. Le problème est que je ne sais pas comment trouver sur quelle cellule un bouton est enfoncé. Je ne reçois actuellement la balise de l'expéditeur que lorsque l'un des boutons a été actionné. Existe-t-il un moyen d’obtenir le numéro de ligne de la cellule aussi bien quand on appuie sur un bouton?
Vous devriez vraiment utiliser cette méthode à la place:
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
Version rapide:
let buttonPosition = sender.convert(CGPoint(), to:tableView)
let indexPath = tableView.indexPathForRow(at:buttonPosition)
Cela vous donnera la indexPath
en fonction de la position du bouton sur lequel vous avez appuyé. Ensuite, vous appelez simplement cellForRowAtIndexPath
si vous avez besoin de la cellule ou indexPath.row
si vous avez besoin du numéro de ligne.
Si vous êtes paranoïaque, vous pouvez vérifier if (indexPath) ...
avant de l'utiliser au cas où la variable indexPath
ne serait pas trouvée pour ce point dans la vue tableau.
Toutes les autres réponses risquent de ne pas aboutir si Apple décide de modifier la structure de la vue.
Edit: Cette réponse est obsolète. Veuillez utiliser cette méthode à la place
Essaye ça:
-(void)button1Tapped:(id)sender
{
UIButton *senderButton = (UIButton *)sender;
UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];
UITableView* table = (UITableView *)[buttonCell superview];
NSIndexPath* pathOfTheCell = [table indexPathForCell:buttonCell];
NSInteger rowOfTheCell = [pathOfTheCell row];
NSLog(@"rowofthecell %d", rowOfTheCell);
}
Edit: Si vous utilisez contentView, utilisez plutôt ceci pour buttonCell:
UITableViewCell *buttonCell = (UITableViewCell *)senderButton.superview.superview;
Je recommanderais cette méthode pour extraire indexPath de la cellule qui a une sous-vue personnalisée - (compatible avec iOS 7 ainsi que toutes les versions précédentes)
-(void)button1Tapped:(id)sender {
//- (void)cellSubviewTapped:(UIGestureRecognizer *)gestureRecognizer {
// UIView *parentCell = gestureRecognizer.view.superview;
UIView *parentCell = sender.superview;
while (![parentCell isKindOfClass:[UITableViewCell class]]) { // iOS 7 onwards the table cell hierachy has changed.
parentCell = parentCell.superview;
}
UIView *parentView = parentCell.superview;
while (![parentView isKindOfClass:[UITableView class]]) { // iOS 7 onwards the table cell hierachy has changed.
parentView = parentView.superview;
}
UITableView *tableView = (UITableView *)parentView;
NSIndexPath *indexPath = [tableView indexPathForCell:(UITableViewCell *)parentCell];
NSLog(@"indexPath = %@", indexPath);
}
Cela ne nécessite pas non plus self.tablview
.
Notez également le code commenté, qui est utile si vous souhaitez que le même élément soit ajouté à @selector of UIGestureRecognizer ajouté à votre sous-vue personnalisée.
Il y a deux manières:
@ H2CO3 a raison. Vous pouvez faire ce que @ user523234 a suggéré, mais avec une petite modification, de respecter le UITableViewCellContentView qui doit se trouver entre UIButton et UITableViewCell. Donc pour modifier son code:
- (IBAction)button1Tapped:(id)sender
{
UIButton *senderButton = (UIButton *)sender;
UITableViewCellContentView *cellContentView = (UITableViewCellContentView *)senderButton.superview;
UITableViewCell *tableViewCell = (UITableViewCell *)cellContentView.superview;
UITableView* tableView = (UITableView *)tableViewCell.superview;
NSIndexPath* pathOfTheCell = [tableView indexPathForCell:tableViewCell];
NSInteger rowOfTheCell = pathOfTheCell.row;
NSLog(@"rowofthecell %d", rowOfTheCell);
}
Si vous créez une UITableViewCell personnalisée (votre propre sous-classe), vous pouvez simplement appeler self
dans IBAction. Vous pouvez lier la fonction IBAction à votre bouton en utilisant le storyboard ou par programme lorsque vous configurez la cellule.
- (IBAction)button1Tapped:(id)sender
{
UITableView* tableView = (UITableView *)self.superview;
NSIndexPath* pathOfTheCell = [tableView indexPathForCell:self];
NSInteger rowOfTheCell = pathOfTheCell.row;
NSLog(@"rowofthecell %d", rowOfTheCell);
}
Je suppose que vous ajoutez des boutons à la cellule dans cellForRowAtIndexPath
, ce que je ferais alors: créer une sous-classe de classe personnalisée UIButton
, ajouter un tag appelé rowNumber
et ajouter ces données tout en ajoutant un bouton à une cellule.
Un autre moyen simple:
Obtenez le point de contact dans tableView
Puis obtenir le chemin d'index de la cellule au point
Le chemin de l'index contient l'index de la ligne
Le code est:
- (void)buttonTapped:(id)sender {
UITapGestureRecognizer *tap = (UITapGestureRecognizer *)sender;
CGPoint point = [tap locationInView:theTableView];
NSIndexPath *theIndexPath = [theTableView indexPathForRowAtPoint:point];
NSInteger theRowIndex = theIndexPath.row;
// do your stuff here
// ...
}
Swift 3
Note: Ceci devrait vraiment aller dans la réponse acceptée ci-dessus, sauf que méta fronce les sourcils lors de telles modifications.
@IBAction func doSomething(_ sender: UIButton) {
let buttonPosition = sender.convert(CGPoint(), to: tableView)
let index = tableView.indexPathForRow(at: buttonPosition)
}
Deux commentaires mineurs:
Je voudrais partager le code dans Swift -
extension UITableView
{
func indexPathForCellContainingView(view1:UIView?)->NSIndexPath?
{
var view = view1;
while view != nil {
if (view?.isKindOfClass(UITableViewCell) == true)
{
return self.indexPathForCell(view as! UITableViewCell)!
}
else
{
view = view?.superview;
}
}
return nil
}
}
Une solution pourrait consister à vérifier la balise de la vue d'ensemble du bouton ou même plus haut dans la hiérarchie de la vue (si le bouton est dans la vue du contenu de la cellule).
En rapide:
@IBAction func buttonAction(_ sender: UIButton) {
guard let indexPath = tableView.indexPathForRow(at: sender.convert(CGPoint(), to: tableView)) else {
return
}
// do something
}