Ajout d'iOS UITableView HeaderView (pas d'en-tête de section)

167

Je souhaite ajouter un en-tête de tableau (pas des en-têtes de section) comme dans l'application Contacts par exemple: entrez la description de l'image ici

exactement comme ça - une étiquette à côté d'une image au-dessus du tableau.

Je veux que toutes les vues soient déroulantes afin que je ne puisse pas les placer en dehors du tableau.

Comment puis je faire ça?

Assaf b
la source

Réponses:

245

UITableViewa une tableHeaderViewpropriété. Réglez-le sur la vue que vous voulez là-haut.

Utilisez un nouveau UIViewcomme conteneur, ajoutez une étiquette de texte et une vue d'image à ce nouveau UIView, puis définissez-le tableHeaderViewsur la nouvelle vue.

Par exemple, dans un UITableViewController:

-(void)viewDidLoad
{
     // ...
     UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(XXX, YYY, XXX, YYY)];
     UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(XXX, YYY, XXX, YYY)];
     [headerView addSubview:imageView];
     UILabel *labelView = [[UILabel alloc] initWithFrame:CGRectMake(XXX, YYY, XXX, YYY)];
     [headerView addSubview:labelView];
     self.tableView.tableHeaderView = headerView;
     [imageView release];
     [labelView release];
     [headerView release];
     // ...
} 
Peterjb
la source
Génial! Merci ça marche. Y a-t-il une propriété de faire grossir les cellules de tableview aussi grandes que le texte à l'intérieur?
Assaf b
Pour ce faire, vous devez être en mesure de calculer la hauteur de la cellule à partir d'une chaîne et de transmettre cette valeur pour heightForRowAtIndexPath. Vous pouvez utiliser la méthode sizeWithFont: constrainedToSize: function de NSString pour déterminer la hauteur du texte lorsqu'il est contraint à une taille.
Mark
Ajoutez-le après la mise en page, ou sa taille ne sera pas souhaitée. Et viewDidLoad est un bon endroit.
BollMose
Est-ce une bonne pratique de définir la géométrie de la vue pendant la phase in viewDidLoad?
Nandish A
1
ok si vous définissez la vue d'en-tête dans la source des tables, cela semble fonctionner, assurez-vous de définir également la hauteur: exemple:public override UIView GetViewForHeader(UITableView tableView, nint section) { return headerView; } public override nfloat GetHeightForHeader(UITableView tableView, nint section) { return headerView.Frame.Height; }
panthor314
193

Vous pouvez le faire assez facilement dans Interface Builder. Créez simplement une vue avec une table et déposez une autre vue sur la table. Cela deviendra la vue d'en-tête du tableau. Ajoutez vos étiquettes et votre image à cette vue. Voir la photo ci-dessous pour la hiérarchie des vues. Afficher la hiérarchie dans Interface Builder

Kirby Todd
la source
12
Je préfère cette réponse car pourquoi écrire du code quand je peux le configurer et le positionner proprement dans IB
Besi
1
génial merci pour l'indice. BTW, vous n'avez pas besoin d'une vue de défilement dans votre en-tête au cas où quelqu'un d'autre se demanderait ou essayerait cela. Il utilise le ScrollView de UITableView pour votre en-tête, car l'en-tête fait techniquement partie de UITableView
Rob R.
2
Il vaut la peine de mentionner comment cela fonctionne dans l'éditeur StoryBoard maintenant: stackoverflow.com/q/7841167/926907
Dmitry Zaytsev
N'utilisez pas de pointe pour cela. Prend plus de temps à charger. Écrivez-le dans le code. Pour la réutilisabilité, créez une classe personnalisée et instanciez ...
Charles Robertson
1
Cela ne me permettra pas d'ajouter une contrainte de hauteur à la vue d'en-tête.
Ian Warburton
14

Dans Swift :

override func viewDidLoad() {
    super.viewDidLoad()

    // We set the table view header.
    let cellTableViewHeader = tableView.dequeueReusableCellWithIdentifier(TableViewController.tableViewHeaderCustomCellIdentifier) as! UITableViewCell
    cellTableViewHeader.frame = CGRectMake(0, 0, self.tableView.bounds.width, self.heightCache[TableViewController.tableViewHeaderCustomCellIdentifier]!)
    self.tableView.tableHeaderView = cellTableViewHeader

    // We set the table view footer, just know that it will also remove extra cells from tableview.
    let cellTableViewFooter = tableView.dequeueReusableCellWithIdentifier(TableViewController.tableViewFooterCustomCellIdentifier) as! UITableViewCell
    cellTableViewFooter.frame = CGRectMake(0, 0, self.tableView.bounds.width, self.heightCache[TableViewController.tableViewFooterCustomCellIdentifier]!)
    self.tableView.tableFooterView = cellTableViewFooter
}
Roi-sorcier
la source
L'utilisation de cette approche pour iOS 7 ou supérieur déclenchera un avertissement d'exécution: "aucun chemin d'index pour la cellule de table réutilisée". Pour éviter cette erreur,
consultez le
11

Vous pouvez également simplement créer UNIQUEMENT un UIView dans le générateur d'interface et faire glisser et déposer l'ImageView et UILabel (pour le faire ressembler à votre en-tête souhaité), puis l'utiliser.

Une fois que votre UIView ressemble à ce que vous voulez, vous pouvez l'initialiser par programme à partir du XIB et l'ajouter à votre UITableView. En d'autres termes, vous n'avez pas à concevoir la table ENTIÈRE dans IB. Juste l'en-têteView (de cette façon, la vue d'en-tête peut également être réutilisée dans d'autres tables)

Par exemple, j'ai un UIView personnalisé pour l'un de mes en-têtes de tableau. La vue est gérée par un fichier xib appelé "CustomHeaderView" et elle est chargée dans l'en-tête du tableau à l'aide du code suivant dans ma sous-classe UITableViewController:

-(UIView *) customHeaderView {
    if (!customHeaderView) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomHeaderView" owner:self options:nil];
    }

    return customHeaderView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Set the CustomerHeaderView as the tables header view 
    self.tableView.tableHeaderView = self.customHeaderView;
}
iansari
la source
-36
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {

    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0,tableView.frame.size.width,30)];
    headerView.backgroundColor=[[UIColor redColor]colorWithAlphaComponent:0.5f];
    headerView.layer.borderColor=[UIColor blackColor].CGColor;
    headerView.layer.borderWidth=1.0f;

    UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 5,100,20)];

    headerLabel.textAlignment = NSTextAlignmentRight;
    headerLabel.text = @"LeadCode ";
    //headerLabel.textColor=[UIColor whiteColor];
    headerLabel.backgroundColor = [UIColor clearColor];


    [headerView addSubview:headerLabel];

    UILabel *headerLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, headerView.frame.size.width-120.0, headerView.frame.size.height)];

    headerLabel1.textAlignment = NSTextAlignmentRight;
    headerLabel1.text = @"LeadName";
    headerLabel.textColor=[UIColor whiteColor];
    headerLabel1.backgroundColor = [UIColor clearColor];

    [headerView addSubview:headerLabel1];

    return headerView;

}
Priyam
la source
Vous n'avez pas compris votre question?
Priyam
2
C'est faux. Il ne veut qu'un seul en-tête de table PAS un en-tête de section. Les deux choses sont très différentes. Veuillez lire la question.
Charles Robertson