web-dev-qa-db-fra.com

Comment un UITableViewCell peut-il connaître son propre indexPath?

Le style standard Grouped UITableView permet à UITableViewCells d’être dessiné avec des coins arrondis en haut et en bas de chaque section. Comment est-ce accompli? Comment la cellule connaît-elle son emplacement dans sa section et comment savoir quand changer ses bords arrondis?

Je veux créer mes propres cellules arrondies et j'ai des images à utiliser, mais je ne sais pas quand montrer quelle image

Remarque: Je sais déjà comment fonctionne UITableView et je sais comment l'utiliser. Je pensais juste que, puisque UITableView était capable de dessiner automatiquement des coins arrondis aux bons endroits, je devrais pouvoir le faire aussi, sans avoir besoin d'ajouter quoi que ce soit à ma source de données ou à mon délégué.

26
Ed Marty

Il existe une méthode sectionLocation de UITableViewCell qui renvoie un entier vous indiquant ce dont vous avez besoin: 

  • 1 - cellule du milieu
  • 2 - cellule supérieure
  • 3 - cellule inférieure
  • 4 - cellule unique

Je n'ai eu aucun problème à utiliser cela dans plusieurs applications de production depuis 2010. 

UPDATE: l'un de nos fichiers binaires a été automatiquement rejeté récemment (fin 2018) parce que nous utilisions la propriété 'sectionLocation', ce n'est donc plus une bonne option.

Ajoutez quelque chose comme ceci dans vos fichiers d'en-tête et vous pourrez l'utiliser:

typedef NS_ENUM(NSInteger, MMMTableViewCellLocation) {

    MMMTableViewCellLocationUndefined = 0,
    MMMTableViewCellLocationMiddle = 1,
    MMMTableViewCellLocationTop = 2,
    MMMTableViewCellLocationBottom = 3,
    MMMTableViewCellLocationSingle = 4
};

@interface UITableViewCell ()

/** Undocumented method of UITableViewCell which allows to know where within section the cell is located,
 * so the cell can draw its borders properly. */
- (MMMTableViewCellLocation)sectionLocation;

/** Override this one to know when the value of sectionLocation changes. */
- (void)setSectionLocation:(MMMTableViewCellLocation)sectionLocation animated:(BOOL)animated;

@end
8
aleh
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
int rows = [(UITableView *)self.superview numberOfRowsInSection:indexPath.section];

if (indexPath.row == 0 && rows == 1) {
// the one and only cell in the section
}
else if (indexPath.row == 0) {
//top
}
else if (indexPath.row != rows - 1) {
//middle
}
else {
//bottom
}
61
Darren Inksetter

C'est très simple. supposons que la cellule est l’objet dont la position doit être déterminée.

  UITableView* table = (UITableView *)[cell superview]; 
  NSIndexPath* pathOfTheCell = [table indexPathForCell:cell]; 
  NSInteger sectionOfTheCell = [pathOfTheCell section]; 
  NSInteger rowOfTheCell = [pathOfTheCell row];
32
J.J.

Vous pouvez utiliser

- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell

pour ce numéro. Dans mon exemple, je l'utilise pour faire défiler la cellule (avec un contenu personnalisé) vers le haut de la vue.

4
xna

Si vous avez besoin de fonctionnalités plus robustes et plus générales, consultez http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html - Matt Gallagher montre ce dont vous avez besoin, assez efficacement. Il recrée essentiellement UITableViewController à partir de UIViewController, tout en ajoutant la possibilité d'utiliser vos propres graphiques personnalisés. Je travaille juste à appliquer ceci à l'un de mes projets, jusqu'à présent, il semblerait que cela ferait l'affaire.

1
Aleksandar Vacić

Malheureusement, je n’ai trouvé aucune solution à ce problème et j’ai eu recours à une sous-classe UITableViewController et UITableViewCell pour en faire une solution générique que je peux étendre au besoin.

0
Ed Marty

Sans entrer dans qui dessine quoi, vous pouvez savoir quelle cellule est la dernière cellule de sa section à l'intérieur de cellForRowAtIndexPath très facilement.

Vous êtes passé dans le chemin indexPath de la cellule que vous devez fournir, non? Vous avez également passé la tableView.

appelez [tableView numberofRowsInSection: indexPath.section] et si c'est == ([indexPath.row] -1), vous savez qu'il vous est demandé de fournir la dernière cellule de cette section.

Au moment de l'appel de cellForRowAtIndexPath, il est garanti que la cellule se trouve au chemin indexPath transmis.

0
God of Biscuits

Pour développer la réponse de Darren (que j'ai trouvée la plus utile, merci, Darren!), Vous pouvez parcourir l'ensemble des superviews jusqu'à ce que vous trouviez le parent UITableView. Cela devrait être une preuve pour le futur puisque vous ne comptez pas sur une hiérarchie fixe de vues.

J'utilise une méthode récursive qui renverra UITableView si elle en trouve une ou nil s'il n'y en a pas.

- (UITableView *)parentTableViewOf:(UIView *)view {
        Class class = [view.superview class];
        NSLog(@"Class : %@", NSStringFromClass(class));

        if([view.superview isKindOfClass:[UITableView class]]) {
            return (UITableView *)view.superview;
        } else {
            return [self parentTableViewOf:view.superview];
        }

        return nil;
}

Jusqu'ici, j'ai utilisé celui-ci et il semble fonctionner sans hoquet. J'espère que ça aide! :)

0
D6mi

Tu ne fais pas ça en cellule. Les coins arrondis sont dessinés dans [tableView viewForHeaderInSection] et viewForFooterInSection.

La façon dont je le fais est d'utiliser le style Plain tableview, puis d'utiliser ces deux vues pour la rondeur et les cellules sont normales, pas de rondes.

0
Aleksandar Vacić