web-dev-qa-db-fra.com

Développement et réduction des cellules de vue de tableau dans iOS

J'ai une vue sous forme de tableau de cellules personnalisées et de certains boutons dans chaque cellule.Cliquer sur l'un des boutons à l'intérieur de la cellule révèlera une autre vue personnalisée en dessous de cette cellule.Le prochain clic sur le même bouton réduira la vue et en aura besoin pour toutes les cellules J'ai essayé avec la méthode insertrow sur le bouton, mais en vain. Comment puis-je le faire en utilisant uniquement les délégués de vue de table.

Voici ce que j'ai essayé:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"CustomCell_For_Dashboard";

    CustomCellFor_Dashboard  *customCell = (CustomCellFor_Dashboard *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    if (customCell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCellFor_Dashboard" owner:self options:nil];
        customCell = [nib objectAtIndex:0];
    }
    [customCell.howyoulfeelBtn  addTarget:self action:@selector(buttonclicked:) forControlEvents:UIControlEventTouchUpInside];
      customCell.nameLabel.text = @"test";
    customCell.imgView.image = [UIImage imageNamed:@"Default.png"];
   // customCell.prepTimeLabel.text = [prepTime objectAtIndex:indexPath.row];
    return customCell;
}

-(void)buttonclicked:(id)sender{
    NSIndexPath *indexPath = [myTable indexPathForCell:sender];


    [myTable beginUpdates];

     NSIndexPath *insertPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
   [myTable insertRowsAtIndexPaths:[NSArray arrayWithObject:insertPath] withRowAnimation:UITableViewRowAnimationTop];
  } 

quelqu'un peut-il m'aider?

20
iOS Developer

J'ai eu la même tâche sur un projet avec une seule chose différente: il n'y avait pas de boutons, il suffit de taper sur la cellule pour l'agrandir ou la réduire.

Il y a plusieurs choses que vous devez modifier dans votre code. Tout d'abord, le code de la méthode du bouton ressemblera à ceci:

- (void) collapseExpandButtonTap:(id) sender
{
    UIButton* aButton = (UIButton*)sender; //It's actually a button
    NSIndexPath* aPath = [self indexPathForCellWithButtonTag:aButton.tag]; //Let's assume that you have only one section and button tags directly correspond to rows of your cells.
    //expandedCells is a mutable set declared in your interface section or private class extensiont
    if ([expandedCells containsObject:aPath])
    {
        [expandedCells removeObject:aPath];
    }
    else
    {
        [expandedCells addObject:aPath];
    }
    [myTableView beginEditing];
    [myTableView endEditing]; //Yeah, that old trick to animate cell expand/collapse
}

Maintenant, la deuxième chose est la méthode UITableViewDelegate:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([expandedCells containsObject:indexPath])
    {
        return kExpandedCellHeight; //It's not necessary a constant, though
    }
    else
    {
        return kNormalCellHeigh; //Again not necessary a constant
    }
}

L'essentiel ici est de déterminer si votre cellule doit être développée/réduite et retourner la bonne hauteur dans la méthode déléguée.

33
eagle.dan.1349

En partant de ce qu'a dit @ eagle.dan.1349, voici comment le faire en cliquant sur la cellule. Dans le storyboard, vous devez également définir la cellule du tableau pour découper les sous-vues, sinon le contenu qui serait masqué s'affichera.

.h

@property (strong, nonatomic) NSMutableArray *expandedCells;

.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    if ([self.expandedCells containsObject:indexPath])
    {
        [self.expandedCells removeObject:indexPath];
    }
    else
    {
        [self.expandedCells addObject:indexPath];
    }
    [tableView beginUpdates];
    [tableView endUpdates];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat kExpandedCellHeight = 150;
    CGFloat kNormalCellHeigh = 50;

    if ([self.expandedCells containsObject:indexPath])
    {
        return kExpandedCellHeight; //It's not necessary a constant, though
    }
    else
    {
        return kNormalCellHeigh; //Again not necessary a constant
    }
}
17
Kalel Wade

Vu ce post et je voulais juste donner mes 2 cents car ma solution à cela est très similaire à la réponse choisie (le tapotement d'une zone entière).

Beaucoup de gens conçoivent cela en utilisant uniquement des cellules seules, mais je pense qu'il existe un moyen de construire cela qui pourrait mieux s'aligner sur ce que les gens essaient de réaliser:

Il y a en-têtes et il y a cellules . Les en-têtes doivent être tappable, puis les cellules sous les en-têtes serait afficher ou masquer. Cela peut être réalisé en ajoutant un identificateur de mouvement à l'en-tête, et lorsque vous appuyez dessus, vous supprimez simplement toutes les cellules sous cet en-tête (la section), et vice versa (ajoutez des cellules). Bien sûr, vous devez conserver l'état des en-têtes "ouverts" et des en-têtes "fermés".

C'est sympa pour plusieurs raisons:

  1. Le travail des en-têtes et des cellules est séparé, ce qui rend le code plus propre.
  2. Cette méthode correspond parfaitement à la façon dont les vues de table sont construites (en-têtes et cellules) et, par conséquent, il n'y a pas beaucoup de magie - le code supprime ou ajoute simplement des cellules et devrait être compatible avec les versions ultérieures d'iOS.

J'ai réalisé une bibliothèque très très simple pour y parvenir. Tant que votre vue de table est configurée avec des en-têtes et des cellules de section UITableView, tout ce que vous avez à faire est de sous-classer la vue de table et l'en-tête.

Lien: https://github.com/fuzz-productions/FZAccordionTableView

enter image description here

8
kgaidis

J'ai également eu une même situation et ma solution a été de mettre un bouton au-dessus du titre de la section avec la méthode viewForHeaderInSection.

noOfRows définit le nombre de lignes dans chaque section et button.tag conserve le bouton de la section sur lequel vous appuyez.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIButton *btnSection = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, tableView.frame.size.height)];
    btnSection.tag = section;   
    [btnSection setTitle:[sectionArray objectAtIndex:section] forState:UIControlStateNormal];
    [btnSection addTarget:self action:@selector(sectionButtonTapped:) forControlEvents:UIControlEventTouchUpInside];

    return btnSection;
} 

- (void)sectionButtonTapped:(UIButton *)button {
    sectionIndex = button.tag;
    if (button.tag == 0) {
        noOfRows = 3;
    } else if (button.tag == 1) {
        noOfRows = 1;
    } else if (button.tag == 2) {
        noOfRows = 2;
    }

    [self.tableView reloadData];
}

J'espère que cela vous aidera..

0
Akila Wasala