UITableView avec en-têtes de section fixes

107

Salutations, je lis que le comportement par défaut de UITableViewest d'épingler les lignes d'en-tête de section en haut du tableau lorsque vous faites défiler les sections jusqu'à ce que la section suivante repousse la ligne de section précédente.

J'ai un UITableViewintérieur UIViewControlleret cela ne semble pas être le cas.

Est-ce juste le comportement par défaut pour UITableViewController?

Voici un code simplifié basé sur ce que j'ai. Je vais montrer l' UIControllerinterface et chaque méthode de vue de table que j'ai implémentée pour créer la vue de table. J'ai une classe de source de données d'assistance qui m'aide à indexer mes objets à utiliser avec la table.

    @interface MyUIViewController ()<UITableViewDelegate, UITableViewDataSource>
        @property (nonatomic, readonly) UITableView *myTableView;
        @property (nonatomic, readonly) MyCustomHelperDataSource *helperDataSource;
    @end

    //when section data is set, get details for each section and reload table on success
    - (void)setSectionData:(NSArray *)sections {
        super.sectionData = sections; //this array drives the sections

        //get additional data for section details
        [[RestKitService sharedClient] getSectionDetailsForSection:someId 
        success:^(RKObjectRequestOperation *operation, RKMappingResult *details) {
            NSLog(@"Got section details data");
            _helperDataSource = [[MyCustomHelperDataSource alloc] initWithSections:sections andDetails:details.array];
            [myTableView reloadData];
        } failure:^(RKObjectRequestOperation *operation, NSError *error) {
            NSLog(@"Failed getting section details");
        }];
    }

    #pragma mark <UITableViewDataSource, UITableViewDelegate>

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        if (!_helperDataSource) return 0;
        return [_helperDataSource countSectionsWithDetails]; //number of section that have details rows, ignore any empty sections
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        //get the section object for the current section int
        SectionObject *section = [_helperDataSource sectionObjectForSection:section];
        //return the number of details rows for the section object at this section
        return [_helperDataSource countOfSectionDetails:section.sectionId];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        UITableViewCell * cell;

        NSString *CellIdentifier = @"SectionDetailCell";

        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
            cell.textLabel.font = [UIFont systemFontOfSize:12.0f];
        }

        //get the detail object for this section
        SectionObject *section = [_helperDataSource sectionObjectForSection:indexPath.section]; 

        NSArray* detailsForSection = [_helperDataSource detailsForSection:section.sectionId] ;
        SectionDetail *sd = (SectionDetail*)[detailsForSection objectAtIndex:indexPath.row];

        cell.textLabel.text = sd.displayText;
        cell.detailTextLabel.text = sd.subText;
        cell.detailTextLabel.textColor = [UIColor blueTextColor];

        return cell;
    }

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 50.0f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 30.0f;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger) section {
    //get the section object for the current section
    SectionObject *section = [_helperDataSource sectionObjectForSection:section]; 

    NSString *title = @"%@ (%d)";

    return [NSString stringWithFormat:title, section.name, [_helperDataSource countOfSectionDetails:section.sectionId]];
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 260, 0)];
    header.autoresizingMask = UIViewAutoresizingFlexibleWidth;

    header.backgroundColor = [UIColor darkBackgroundColor];

    SSLabel *label = [[SSLabel alloc] initWithFrame:CGRectMake(3, 3, 260, 24)];
    label.font = [UIFont boldSystemFontOfSize:10.0f];
    label.verticalTextAlignment = SSLabelVerticalTextAlignmentMiddle;
    label.backgroundColor = [UIColor clearColor];
    label.text = [self tableView:tableView titleForHeaderInSection:section];
    label.textColor = [UIColor whiteColor];
    label.shadowColor = [UIColor darkGrayColor];
    label.shadowOffset = CGSizeMake(1.0, 1.0);
    [header addSubview:label];

    return header;
}
topwik
la source
Cela devrait fonctionner. Montrez du code.
Matthias Bauch
C'est une façon tout à fait correcte d'utiliser un UITableView, et devrait fonctionner avec les en-têtes. Que ne font pas les en-têtes dans votre cas?
Eric
@Eric les en-têtes défilent avec les lignes. Ils ne s'arrêtent pas en haut de la table pendant que je défile. J'ai ajouté le code que j'utilise pour générer ma vue de table. C'est un UITableView à l'intérieur d'un UIViewController.
topwik

Réponses:

305

Les en-têtes ne restent fixes que lorsque la UITableViewStylepropriété de la table est définie sur UITableViewStylePlain. Si vous l'avez défini sur UITableViewStyleGrouped, les en-têtes défileront avec les cellules.

Bachonk
la source
3
mon style tableview est UITableViewStylePlain, mais il défile avec les cellules non plus.
yudun1989
8
Il y a quelques explications possibles à cela. Une note importante est que les en-têtes ne resteront fixes que pour les cellules de sa section. Donc, si vous avez un en-tête dans la section 0, il ne restera pas fixe pour les cellules de la section 1. Une autre explication possible est que vous n'initialisez pas votre UITableView avec le style approprié. Il est recommandé d'utiliser initWithStyle:UITableViewStylePlain, car appeler quelque chose comme tableView.style = UITableViewStylePlain ne fonctionnera pas.
bachonk
UITableViewStyleGrouped rend l'en-tête / pied de page fixé avec d'autres cellules, tandis que UITableViewStylePlain rend l'en-tête / pied de page "flottant" lorsque l'en-tête / pied de page atteint le haut / bas de la vue du tableau.
StoneLam
@bachonk J'utilise une vue d'en-tête extensible. et mon style est UITableViewStyleGrouped. je veux corriger l'en-tête lors du défilement vers le haut. si je le fais UITableViewStylePlain alors l'en-tête se fixe au milieu de l'écran, je veux faire défiler l'en-tête vers le bas, mais lorsque je fais défiler vers le haut, je veux qu'il soit corrigé sur la première ligne .. est-ce possible?
Gorib Developer
3

Changez votre style TableView:

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

Selon la documentation Apple pour UITableView:

UITableViewStylePlain - Une vue de table simple. Tous les en-têtes ou pieds de page de section sont affichés sous forme de séparateurs en ligne et flottent lorsque la vue de tableau est défilée.

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

J'espère que ce petit changement vous aidera.

Aks
la source
2
cela semble être exactement le contraire de ce que la question demandait - ça devrait être Plain, pasGrouped
CupawnTae
1

Swift 3.0

Créez un ViewController avec les protocoles UITableViewDelegate et UITableViewDataSource . Créez ensuite un tableView à l'intérieur, en déclarant que son style est UITableViewStyle.grouped . Cela corrigera les en-têtes.

lazy var tableView: UITableView = {
    let view = UITableView(frame: UIScreen.main.bounds, style: UITableViewStyle.grouped)
    view.delegate = self
    view.dataSource = self
    view.separatorStyle = .none
    return view
}()
Nursultan Askarbekuly
la source
0

Vous pouvez également définir la propriété bounces de tableview sur NO. Cela gardera les en-têtes de section non flottants / statiques, mais vous perdrez également la propriété de rebond de la vue table.

kevinl
la source
0

pour rendre l'en-tête des sections UITableView non collant ou collant:

  1. changez le style de la vue du tableau - rendez-le groupé pour non collant et rendez-le clair pour les en-têtes de section collants - n'oubliez pas: vous pouvez le faire à partir du storyboard sans écrire de code. (cliquez sur votre vue de tableau et changez son style dans le menu latéral droit / composant)

  2. si vous avez des composants supplémentaires tels que des vues personnalisées ou etc., veuillez vérifier les marges de la vue du tableau pour créer un design approprié. (comme la hauteur de l'en-tête pour les sections et la hauteur de la cellule au chemin d'index, les sections)

Burcu Kutluay
la source
-2

Maintenant, votre vue de table ressemble à un style de table simple, mais ne flottez pas le style de table de réglage buz défini sur groupe.

[_tableView setBackgroundView:nil];
_tableView.backgroundColor = [UIColor whiteColor];
Ravi Kumar
la source