web-dev-qa-db-fra.com

Comment supprimer une cellule statique d'un UITableView conçu dans StoryBoard

La solution est probablement très simple, mais je ne pouvais pas la trouver ..!

En travaillant avec le storyboard (iOS 5), j'ai une tableViewController et une table STATIC conçue avec 5 sections, avec différentes cellules statiques à l'intérieur de chaque section.

Ma question est la suivante: comment supprimer une cellule par programmation dans la variable viewWillAppear?

Par exemple, j'ai une cellule conçue pour une date

IBOutlet UITableViewCell * cellForDate;

Et .. s'il n'y a pas de date, je veux enlever ma cellule.

cellForDate.hidden = true; //Hide the cell, but leave a blank space

J'ai essayé [tableView deleteRowsAtIndexPaths...] n'a pas fonctionné

Quelqu'un a une idée?

25
Marc

Essayez de masquer la cellule avant son affichage, dans la méthode UITableViewDelegate ' tableView:willDisplayCell:forRowAtIndexPath: . C'est la dernière méthode permettant de manipuler l'apparence de la cellule. Toutefois, cela ne supprimera pas l'espace que la cellule devrait occuper. Vous pouvez également essayer de définir la hauteur de la ligne de la cellule sur 0 à l'aide de la méthode tableView:heightForRowAtIndexPath: du même protocole.

Une autre méthode, la plus robuste, consiste à concevoir une méthode pour déterminer si vous avez besoin de la cellule de date dans la section et, en fonction du résultat, renvoyer le nombre approprié de lignes dans la section et renvoyer les autres cellules de ligne de section prenant en compte la situation. Compte. Et puis rechargez les données de tableView sur viewWillAppear.

32
macbirdie

J'espère que c'est un peu plus d'une solution universelle, mais ce n'est toujours pas parfait

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
    if (cell.hidden) {
        return 0;
    } else {
        return [super tableView:tableView heightForRowAtIndexPath:indexPath];
    }
}

Avec cette méthode, vous définissez votre cellule liée IBOutlet comme étant masquée, puis lorsque la table essaie d’afficher une ligne, elle vérifie d’abord si la cellule (utilisant le super appel pour obtenir la cellule) doit être masquée, si elle renvoie un hauteur de 0 qui le supprime effectivement de la liste. Si la cellule ne doit pas être cachée, elle prend la hauteur du super afin que tout ce qui se passerait normalement se produise.

Le seul problème avec ceci est que les cellules de début et de fin sont responsables du diviseur en haut et en bas de la liste ou du groupe. Ainsi, si vous masquez la dernière cellule d'un groupe, le séparateur inférieur du groupe sera inséré légèrement comme s'il se trouvait sur des lignes normales plutôt que sur toute la largeur. Ce n'est un problème que si vous masquez les lignes du haut ou du bas ET que vous utilisez un séparateur ET que vous vous souciez d'un affichage totalement standard. La meilleure solution dans mon cas était tout simplement de ne pas masquer les rangées du haut ou du bas. J'ai déplacé tout contenu pouvant être caché au milieu du groupe. Sinon, vous pouvez simplement accepter que ce n'est pas tout à fait standard ou désactiver les séparateurs de lignes sur votre table.

26
ima747

Swift 3

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if indexPath.section == 0 {
        cell.isHidden = true
    }
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.section == 0 {
        return 0
    } else {
        return super.tableView(tableView, heightForRowAt: indexPath)
    }
}
7
Henry

Si vous souhaitez supprimer définitivement la cellule tableview, appelez simplement deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone] avec le chemin indexPath correspondant à votre ligne. Vous devrez également décrémenter le nombre de lignes renvoyées par numberOfRowsInSection:.

Cependant, je cherchais un moyen de "supprimer" temporairement des cellules tableview statiques non désirées d'une tableview statique, car je voulais qu'une ligne particulière soit présente parfois, et d'autres fois non. Je voulais aussi pouvoir mettre à jour cela à la demande depuis l'extérieur du contrôleur de tableview.

Mon cas est assez simple, puisque c’est la première ligne qui était affichée ou masquée. Vous pouvez généraliser pour répondre à vos propres besoins. Mon contrôleur tableview est mon délégué de source de données.

Tout d'abord, j'ai créé une méthode publique dans le contrôleur tableview pour mettre à jour les variables d'état et déclencher le réaffichage:

- (void)updateSettingsDisplay:(BOOL)hideSetting
{
    if (hideSetting == self.hideSetting) {
        return; // no need to do anything because it didn't change
    }

    self.hideSetting = hideSetting;
    self.numRows = (hideSetting)? kNumRowsWithSetting : kNumRowsWithoutSetting;

    // redisplay only if we're visible
    if (!self.viewJustLoaded && (self.navController.visibleViewController == self)) {
        [self.tableView reloadData];
    }
    self.viewJustLoaded = NO;
}

La variable viewDidLoad du contrôleur de la vue table ressemble à ceci:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // check whether or not to display out-of-coverage tableview cell
    self.hideSetting = YES; // initial value; could just as easily be NO
    self.viewJustLoaded = YES;
    [self updateSettingsDisplay];
}

Le délégué de source de données de la vue de table:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return self.numRows;
}

et enfin

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // set row to the index of the stored tableView cell that corresponds to the
    // cell you want (its location in the static tableview from your storyboard)
    NSInteger row = indexPath.row;
    if (self.hideSetting) {
        // skip drawing setting's tableviewcell (since the setting we're hiding is
        // first, we can just increment the row to get the one we want)
        ++row;
        assert(row < kTotalRows); // bounds checking just to convince yourself (remove after testing)
    }
    // get a new index path since the row field is read-only
    NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section];

    // grab the cell from super that corresponds to the cell you want
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:newIndexPath]; // static table

    return cell;
}

Le truc, c'est que les cellules statiques sont toujours disponibles dans [super tableView:tableView cellForRowAtIndexPath:newIndexPath] - utilisez-le donc pour le stockage permanent de vos cellules tableview statiques. Puis ajustez le nombre de lignes selon vos besoins et mappez les lignes correctement (c.-à-d., Obtenez la ligne de la cellule stockée qui correspond à la cellule que vous souhaitez afficher) dans le cellForRowAtIndexPath: de votre délégué table vue. 

La méthode updateSettingsDisplay peut être appelée sur votre contrôleur tableview par n'importe quelle classe qui la conserve. Si le contrôleur tableview n'est pas visible lors de son appel, il mettra simplement à jour l'état et attendra la prochaine fois qu'il deviendra visible pour modifier l'affichage.

3
BeccaP
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    if(indexPath.section == 1) { //For example
        return 0
    }
}

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    if(indexPath.section == 1) {
         cell.hidden = true
    }
}
1
Yaman

vous voudrez peut-être regarder ça

https://github.com/xelvenone/StaticDataTableViewController/

usage

self.hideSectionsWithHiddenRows = YES; //YES, NO
[self cell:self.outletToMyStaticCell1 setHidden:hide];
[self cell:self.outletToMyStaticCell2 setHidden:hide];
[self reloadDataAnimated:YES];
0
Peter Lapisu

Pour votre information (si je pouvais commenter), si vous remplacez une UITableView statique groupée à partir du storyboard, vous devrez également remplacer les vues et hauteurs d'en-tête et de pied de page pour chaque section que vous modifiez/masquez.

J'avais également besoin de définir la valeur de retour pour les méthodes "GetHeight" sur autre chose que zéro - ce qui implique qu'une valeur nulle signifie autre chose (autolayout, ou "non défini" ou similaire).

Le code ci-dessous est dans Xamarin iOS C #, mais se traduit directement par les méthodes Obj-C appropriées:

    public override void WillDisplayHeaderView(UITableView tableView, UIView headerView, nint section)
    {
        if (section == 0)
        {
            headerView = new UIView(new CGRect(0,0,0,0));
        }
    }

    public override nfloat GetHeightForHeader(UITableView tableView, nint section)
    {
        if (section == 0)
        {
            return 1f;
        }
        return base.GetHeightForHeader(tableView, section);
    }

    public override void WillDisplayFooterView(UITableView tableView, UIView footerView, nint section)
    {
        if (section == 0)
        {
            footerView = new UIView(new CGRect(0, 0, 0, 0));
        }
    }

    public override nfloat GetHeightForFooter(UITableView tableView, nint section)
    {
        if (section == 0)
        {
            return 1f;
        }
        return base.GetHeightForFooter(tableView, section);
    }
0
Coruscate5