Modifier le comportement de défilement par défaut de l’en-tête de section UITableView

J’ai un UITableView avec deux sections. C’est une vue simple du tableau. J’utilise viewForHeaderInSection pour créer des vues personnalisées pour ces en-têtes. Jusqu’ici tout va bien.

Le comportement de défilement par défaut est que, lorsqu’une section est rencontrée, l’en-tête de la section rest ancré sous la barre de navigation, jusqu’à ce que la section suivante défile.

Ma question est la suivante: puis-je modifier le comportement par défaut de sorte que les en-têtes de section ne restnt PAS ancrés en haut, mais plutôt défiler sous la barre de navigation avec le rest des lignes de la section?

Est-ce que je manque quelque chose d’évident?

Merci.

La façon dont j’ai résolu ce problème est d’ajuster le contentOffset fonction du contentInset dans UITableViewControllerDelegate ( UITableViewControllerDelegate UIScrollViewDelegate ) comme ceci:

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat sectionHeaderHeight = 40; if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=0) { scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0); } else if (scrollView.contentOffset.y>=sectionHeaderHeight) { scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0); } } 

Le seul problème ici est qu’il perd un peu de rebond lors du défilement vers le haut.


{NOTE: Le “40” devrait être la hauteur exacte de votre en-tête de section 0. Si vous utilisez un nombre plus grand que la hauteur de l’en-tête de votre section 0, vous verrez que le toucher du doigt est affecté (essayez “1000” et vous verrez que le comportement de rebond est bizarre en haut). si le nombre correspond à la hauteur de l’en-tête de la section 0, la sensation du doigt semble être parfaite ou presque parfaite.}

Vous pouvez également append une section avec zéro ligne en haut et utiliser simplement le pied de page de la section précédente comme en-tête pour la suivante.

Si c’était ce que je faisais, je profiterais du fait que UITableViews dans le style Plain n’ont pas les en-têtes et ceux du style groupé. J’essaierais probablement d’utiliser au moins une cellule de tableau personnalisée pour reproduire l’apparence des cellules Plain dans une table groupée.

Je n’ai pas vraiment essayé cela, donc cela ne fonctionnera peut-être pas, mais c’est ce que je suggère de faire.

Je sais que c’est tard, mais j’ai trouvé la solution définitive!

Ce que vous voulez faire est que si vous avez 10 sections, laissez le dataSource retourner 20. Utilisez des nombres pairs pour les en-têtes de section et des nombres impairs pour le contenu de la section. quelque chose comme ça

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section%2 == 0) { return 0; }else { return 5; } } -(NSSsortingng *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { if (section%2 == 0) { return [NSSsortingng ssortingngWithFormat:@"%i", section+1]; }else { return nil; } } 

Voilá! :RÉ

Il y a plusieurs choses à faire pour résoudre ce problème de manière non-piratée:

  1. Définissez le style de vue de table sur UITableViewStyleGrouped
  2. Définissez la vue de table backgroundColor sur [UIColor clearColor]
  3. Définissez la vue backgroundView sur chaque cellule de vue de table sur une vue vide avec backgroundColor [UIColor clearColor]
  4. Si nécessaire, définissez la vue de table rowHeight manière appropriée ou remplacez tableView:heightForRowAtIndexPath: si des lignes individuelles ont des hauteurs différentes.

Initialement posté ici , une solution rapide en utilisant l’IB. La même chose peut être faite par programmation, mais assez simplement.

Un moyen probablement plus facile d’y parvenir (en utilisant IB):

Faites glisser un UIView sur votre TableView pour en faire sa vue d’en-tête.

  1. Définissez la hauteur de vue de l’en-tête sur 100px
  2. Définissez la tableview contentInset (top) sur -100
  3. Les en-têtes de section vont maintenant défiler comme n’importe quelle cellule normale.

Certaines personnes ont commenté en disant que cette solution cache le premier en-tête, mais je n’ai pas remarqué un tel problème. Cela a parfaitement fonctionné pour moi et était de loin la solution la plus simple que j’ai vue jusqu’ici.

Je n’étais pas satisfait des solutions décrites jusqu’ici, alors j’ai essayé de les combiner. Le résultat est le code suivant, inspiré par @awulf et @cescofry. Cela fonctionne pour moi parce que je n’ai pas d’en-tête de vue de table réel. Si vous avez déjà un en-tête de vue de table, vous devrez peut-être ajuster la hauteur.

 // Set the edge inset self.tableView.contentInset = UIEdgeInsetsMake(-23.0f, 0, 0, 0); // Add a transparent UIView with the height of the section header (ARC enabled) [self.tableView setTableHeaderView:[[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 23.0f)]]; 

Changez simplement le style de vue de table:

 self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped]; 

Documentation UITableViewStyle :

UITableViewStylePlain – Une vue en tableau simple. Tous les en-têtes de section ou les pieds de page sont affichés en tant que séparateurs en ligne et flottent lorsque vous faites défiler la vue de table.

UITableViewStyleGrouped – Une vue de table dont les sections présentent des groupes de lignes distincts. Les en-têtes de section et les pieds de page ne flottent pas.

Sélectionnez le style GroupView TableView

Sélectionnez le style de vue de table groupée dans l’inspecteur d’atsortingbuts de votre tableView dans le storyboard.

Changez votre style de table:

 self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped]; 

Selon la documentation Apple pour UITableView:

UITableViewStylePlain – Une vue en tableau simple. Tous les en-têtes de section ou les pieds de page sont affichés en tant que séparateurs en ligne et flottent lorsque vous faites défiler la vue de table.

UITableViewStyleGrouped – Une vue de table dont les sections présentent des groupes de lignes distincts. Les en-têtes de section et les pieds de page ne flottent pas. J’espère que ce petit changement vous aidera.

Définir le headerView de la table avec une vue transparente avec la même hauteur de l’en-tête en vue en coupe. Initie également la tableview avec un cadre à la hauteur.

 self.tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, - height, 300, 400)]; UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)] autorelease]; [self.tableView setTableHeaderView:headerView]; 

J’ai trouvé une solution alternative, utiliser la première cellule de chaque section à la place d’une section d’en-tête réelle, cette solution ne semble pas si propre, mais fonctionne si bien, vous pouvez utiliser une cellule prototype définie pour votre section en-têtes et la méthode cellForRowAtIndexPath demandez l’indexPath.row == 0, si true, utilisez la cellule prototype de la section d’en-tête, sinon utilisez votre cellule prototype par défaut.

Maintenant que le style groupé est fondamentalement identique au style simple d’iOS 7 (en termes de planéité et d’arrière-plan), le meilleur et le plus simple (c.-à-d. Le moins piraté) était de changer le style de la vue en groupes. Le assembly avec contentInsets était toujours un problème lorsque nous avons intégré une barre de navigation déroulante en haut. Avec un style de vue de tableau groupé, il est identique (avec nos cellules) et les en-têtes de section restnt fixes. Pas de défilement bizarre.

Atsortingbuez un encart négatif à votre tableView. Si vous avez des en-têtes de section haute 22px, et que vous ne voulez pas qu’ils soient collants, juste après reload, ajoutez:

 self.tableView.contentInset = UIEdgeInsetsMake(-22, 0, 0, 0); self.tableView.contentSize = CGSizeMake(self.tableView.contentSize.width, self.tableView.contentSize.height+22); 

Fonctionne comme un charme pour moi. Fonctionne également pour les pieds de section, il vous suffit d’affecter l’insert négatif en bas à la place.

J’ajoute la table à une vue défilement qui semble bien fonctionner.

Vérifiez ma réponse ici . C’est le moyen le plus simple d’implémenter les en-têtes de section non flottants sans aucun piratage.

La réponse de @ LocoMike correspondait le mieux à ma tableView, mais elle s’est également cassée lors de l’utilisation des pieds de page. Donc, c’est la solution corrigée lors de l’utilisation des en-têtes et des pieds de page:

 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return (self.sections.count + 1) * 3; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section % 3 != 1) { return 0; } section = section / 3; ... } - (NSSsortingng *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { if (section % 3 != 0) { return nil; } section = section / 3; ... } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { if (section % 3 != 0) { return 0; } section = section / 3; ... } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { if (section % 3 != 2) { return 0; } section = section / 3; ... } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { if (section % 3 != 0) { return nil; } section = section / 3; ... } - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { if (section % 3 != 2) { return nil; } section = section / 3; ... } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { int section = indexPath.section; section = section / 3; ... } 

Changez votre style de table:

 self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped]; 

Selon la documentation Apple pour UITableView:

 UITableViewStylePlain- A plain table view. Any section headers or footers are displayed as inline separators and float when the table view is scrolled. UITableViewStyleGrouped- A table view whose sections present distinct groups of rows. The section headers and footers do not float. Hope this small change will help you .. 

Version rapide de la réponse de @awulf, qui fonctionne très bien!

 func scrollViewDidScroll(scrollView: UIScrollView) { let sectionHeight: CGFloat = 80 if scrollView.contentOffset.y <= sectionHeight { scrollView.contentInset = UIEdgeInsetsMake( -scrollView.contentOffset.y, 0, 0, 0) }else if scrollView.contentOffset.y >= sectionHeight { scrollView.contentInset = UIEdgeInsetsMake(-sectionHeight, 0, 0, 0) } } 

J’ai appris que le fait de définir la propriété tableHeaderView le fait, c’est-à-dire:

  tableView.tableHeaderView = customView; 

et c’est tout.