Je sais que cette question concernait iOS 5, mais pour le bénéfice des futurs lecteurs, notez que l'iOS 6 efficace que nous pouvons maintenant utiliser à la dequeueReusableHeaderFooterViewWithIdentifier
place dequeueReusableCellWithIdentifier
.
Alors viewDidLoad
, appelez soit registerNib:forHeaderFooterViewReuseIdentifier:
ou registerClass:forHeaderFooterViewReuseIdentifier:
. Ensuite viewForHeaderInSection
, appelez tableView:dequeueReusableHeaderFooterViewWithIdentifier:
. Vous n'utilisez pas de prototype de cellule avec cette API (il s'agit d'une vue basée sur NIB ou d'une vue créée par programme), mais il s'agit de la nouvelle API pour les en-têtes et pieds de page retirés de la file d'attente.
Utilisez simplement une cellule prototype comme en-tête et / ou pied de page de votre section.
tableView:viewForHeaderInSection:
méthode ou latableView:viewForFooterInSection:
méthode[tableView dequeueReusableCellWithIdentifier:]
pour obtenir l'en-têtetableView:heightForHeaderInSection:
méthode.-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { static NSString *CellIdentifier = @"SectionHeader"; UITableViewCell *headerView = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (headerView == nil){ [NSException raise:@"headerView == nil.." format:@"No cells with matching CellIdentifier loaded from your storyboard"]; } return headerView; }
Edit: Comment changer le titre de l'en-tête (question commentée):
tableView:viewForHeaderInSection:
méthode, obtenez l'étiquette en appelant:UILabel *label = (UILabel *)[headerView viewWithTag:123];
[label setText:@"New Title"];
la source
viewForHeaderInSection
méthode (pas besoin d'ajouter des UIViews personnalisées).dequeueReusableHeaderFooterViewWithIdentifier
est introduit et est maintenant préféré à cette réponse. Mais l'utiliser correctement nécessite maintenant plus d'étapes. J'ai le guide @ samwize.com/2015/11/06/… .UITableViewCell
comme vue d'en-tête. Il vous sera très difficile de déboguer les problèmes visuels - l'en-tête disparaîtra parfois à cause de la façon dont les cellules sont retirées de la file d'attente et vous chercherez pendant des heures pourquoi jusqu'à ce que vous réalisiez qu'ilUITableViewCell
n'appartient pas à l'en-UITableView
tête.Dans iOS 6.0 et supérieur, les choses ont changé avec la nouvelle
dequeueReusableHeaderFooterViewWithIdentifier
API.J'ai rédigé un guide (testé sur iOS 9), qui peut se résumer ainsi:
UITableViewHeaderFooterView
viewDidLoad
viewForHeaderInSection
et utiliserdequeueReusableHeaderFooterViewWithIdentifier
pour récupérer l'en-tête / pied de pagela source
Je l'ai fait fonctionner dans iOS7 en utilisant une cellule prototype dans le storyboard. J'ai un bouton dans ma vue d'en-tête de section personnalisée qui déclenche une séquence configurée dans le storyboard.
Commencez avec la solution de Tieme
Comme le souligne pedro.m, le problème avec ceci est que le fait d'appuyer sur l'en-tête de section provoque la sélection de la première cellule de la section.
Comme le souligne Paul Von, cela est résolu en renvoyant le contentView de la cellule au lieu de la cellule entière.
Cependant, comme le souligne Hons, un appui long sur ledit en-tête de section plantera l'application.
La solution consiste à supprimer tous les gestureRecognizers de contentView.
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { static NSString *CellIdentifier = @"SectionHeader"; UITableViewCell *sectionHeaderView = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; while (sectionHeaderView.contentView.gestureRecognizers.count) { [sectionHeaderView.contentView removeGestureRecognizer:[sectionHeaderView.contentView.gestureRecognizers objectAtIndex:0]]; } return sectionHeaderView.contentView; }
Si vous n'utilisez pas de gestes dans vos vues d'en-tête de section, ce petit hack semble le faire.
la source
Si vous utilisez des storyboards, vous pouvez utiliser une cellule prototype dans la vue tableau pour mettre en page votre vue d'en-tête. Définissez un identifiant unique et viewForHeaderInSection, vous pouvez retirer la cellule avec cet ID et la convertir en UIView.
la source
Si vous avez besoin d'une implémentation Swift de ceci, suivez les instructions sur la réponse acceptée, puis dans vous UITableViewController implémentez les méthodes suivantes:
la source
La solution que j'ai proposée est fondamentalement la même solution utilisée avant l'introduction des storyboards.
Créez un nouveau fichier de classe d'interface vide. Faites glisser un UIView sur la toile, mise en page comme vous le souhaitez.
Chargez la pointe manuellement, affectez à la section d'en-tête / pied de page appropriée dans les méthodes déléguées viewForHeaderInSection ou viewForFooterInSection.
J'avais espéré qu'Apple simplifiait ce scénario avec des storyboards et continuait à chercher une solution meilleure ou plus simple. Par exemple, les en-têtes et pieds de page de tableau personnalisés sont faciles à ajouter.
la source
tableView:titleForHeaderInSection
, qui est une ligne unique.Lorsque vous renvoyez le contenu de la cellule, vous aurez 2 problèmes:
viewForHeaderInSection
appel, vous créez une nouvelle cellule)Solution:
Classe wrapper pour l'en-tête \ pied de page de la table. C'est juste un conteneur, hérité de
UITableViewHeaderFooterView
, qui contient la cellulehttps://github.com/Magnat12/MGTableViewHeaderWrapperView.git
Enregistrez la classe dans votre UITableView (par exemple, dans viewDidLoad)
- (void)viewDidLoad { [super viewDidLoad]; [self.tableView registerClass:[MGTableViewHeaderWrapperView class] forHeaderFooterViewReuseIdentifier:@"ProfileEditSectionHeader"]; }
Dans votre UITableViewDelegate:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { MGTableViewHeaderWrapperView *view = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"ProfileEditSectionHeader"]; // init your custom cell ProfileEditSectionTitleTableCell *cell = (ProfileEditSectionTitleTableCell * ) view.cell; if (!cell) { cell = [tableView dequeueReusableCellWithIdentifier:@"ProfileEditSectionTitleTableCell"]; view.cell = cell; } // Do something with your cell return view; }
la source
J'avais l'habitude de faire ce qui suit pour créer paresseusement des vues d'en-tête / pied de page:
[NSNull null]
la source
J'ai eu des problèmes dans un scénario où Header n'a jamais été réutilisé, même en effectuant toutes les étapes appropriées.
Donc, comme une note de conseil à tous ceux qui veulent obtenir la situation de montrer les sections vides (0 lignes), soyez averti que:
dequeueReusableHeaderFooterViewWithIdentifier ne réutilise pas l'en-tête tant que vous n'avez pas renvoyé au moins une ligne
J'espère que cela aide
la source
Similaire à laszlo answer mais vous pouvez réutiliser la même cellule prototype pour les cellules du tableau et la cellule d'en-tête de section. Ajoutez les deux premières fonctions ci-dessous à votre sous-classe UIViewController
la source
Pour faire suite à la suggestion de Damon , voici comment j'ai rendu l'en-tête sélectionnable comme une ligne normale avec un indicateur de divulgation.
J'ai ajouté un Button sous-classé de UIButton (nom de sous-classe "ButtonWithArgument") à la cellule prototype de l'en-tête et supprimé le texte du titre (le texte en gras "Titre" est un autre UILabel dans la cellule prototype)
puis définissez le bouton sur la vue entière de l'en-tête et ajouté un indicateur de divulgation avec l'astuce d' Avario
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { static NSString *CellIdentifier = @"PersonGroupHeader"; UITableViewCell *headerView = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(headerView == nil) { [NSException raise:@"headerView == nil, PersonGroupTableViewController" format:[NSString stringWithFormat:@"Storyboard does not have prototype cell with identifier %@",CellIdentifier]]; } // https://stackoverflow.com/a/24044628/3075839 while(headerView.contentView.gestureRecognizers.count) { [headerView.contentView removeGestureRecognizer:[headerView.contentView.gestureRecognizers objectAtIndex:0]]; } ButtonWithArgument *button = (ButtonWithArgument *)[headerView viewWithTag:4]; button.frame = headerView.bounds; // set tap area to entire header view button.argument = [[NSNumber alloc] initWithInteger:section]; // from ButtonWithArguments subclass [button addTarget:self action:@selector(headerViewTap:) forControlEvents:UIControlEventTouchUpInside]; // https://stackoverflow.com/a/20821178/3075839 UITableViewCell *disclosure = [[UITableViewCell alloc] init]; disclosure.accessoryType = UITableViewCellAccessoryDisclosureIndicator; disclosure.userInteractionEnabled = NO; disclosure.frame = CGRectMake(button.bounds.origin.x + button.bounds.size.width - 20 - 5, // disclosure 20 px wide, right margin 5 px (button.bounds.size.height - 20) / 2, 20, 20); [button addSubview:disclosure]; // configure header title text return headerView.contentView; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 35.0f; } -(void) headerViewTap:(UIGestureRecognizer *)gestureRecognizer; { NSLog(@"header tap"); NSInteger section = ((NSNumber *)sender.argument).integerValue; // do something here }
ButtonWithArgument.h
#import <UIKit/UIKit.h> @interface ButtonWithArgument : UIButton @property (nonatomic, strong) NSObject *argument; @end
ButtonWithArgument.m
#import "ButtonWithArgument.h" @implementation ButtonWithArgument @end
la source
Vous devriez utiliser la solution de Tieme comme base, mais oubliez les
viewWithTag:
approches louche et les autres, essayez plutôt de recharger votre en-tête (en rechargeant cette section).Donc, après avoir installé votre vue d'en-tête de cellule personnalisée avec tous les
AutoLayout
éléments sophistiqués , retirez-la simplement de la file d'attente et renvoyez le contentView après votre configuration, comme:la source
Qu'en est-il d'une solution où l'en-tête est basé sur un tableau de vues:
Suivant dans le délégué:
la source
Ajouter une cellule
StoryBoard
et définirreuseidentified
Code
et
Utilisation:
la source
Voici la réponse de @Vitaliy Gozhenko , dans Swift.
Pour résumer, vous allez créer un UITableViewHeaderFooterView qui contient un UITableViewCell. Ce UITableViewCell sera "retirable" et vous pourrez le concevoir dans votre storyboard.
Créer une classe UITableViewHeaderFooterView
Branchez votre tableview avec cette classe dans votre fonction viewDidLoad:
Lorsque vous demandez un en-tête de section, retirez un CustomHeaderFooterView de la file d'attente et insérez-y une cellule
la source