60 votes

Table de accordéon - Comment développer / contracter dynamiquement uitableviewcell?

Je suis en train de créer un accordéon type de uitableviewcell que, lorsque l'utilisateur sélectionne la cellule, il se développe pour afficher une info détaillée de vue inline similaire à la façon dont les digg application fonctionne. J'ai d'abord essayé de remplacer l'actuel tablecell avec un customcell dans cellForRowAtIndex cependant, l'animation est un peu agitée comme vous pouvez le voir la cellule remplacé, et dans l'ensemble, l'effet ne fonctionne pas bien.

Si vous regardez les digg app et d'autres qui ont fait cela, il semble qu'ils n'en remplacement de l'actuelle cellule, mais plutôt peut-être l'ajout d'un sous-vue à la cellule? La cellule d'origine cependant ne semble pas animer à tous et seule la nouvelle vue des accordéons dans la table.

Quelqu'un a une idée comment faire pour obtenir un effet similaire?

Mise à jour: J'ai fait des progrès à l'aide de neha la méthode ci-dessous, et alors que la cellule est l'animation de la bonne manière, il fait des ravages avec les autres cellules du tableau. Ce que j'ai fait est sous-classé UITableViewCell avec une classe personnalisée qui contient une instance d'une UIView qui, de fait, attire le regard que je puis ajouter à la table de cellules contentview.

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

if (selected) { 
    [self expandCell];
}
}

-(void)expandCell { 
    self.contentView.frame = CGRectMake(0.0, 0.0, self.contentView.bounds.size.width, 110);
}

Voici le tableau délégué méthodes, je suis en utilisant:

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

if (isSearching && indexPath.row == selectedIndex) {

    static NSString *CellIdentifier = @"SearchCell";
    CustomTableCell *cell = (CustomTableCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    [cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];

    UILabel *theText = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 10.0, cell.contentView.bounds.size.width -20, 22.0)];
    theText.text = @"Title Text";
    [cell.contentView addSubview:theText];


    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 10 + 46.0, cell.contentView.bounds.size.width - 20, 40.0)];
    textField.borderStyle = UITextBorderStyleLine;
    [cell.contentView addSubview:textField];        

    UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 88.0, cell.contentView.bounds.size.width - 20, 22.0)];
    testLabel.text = [NSString stringWithFormat:@"Some text here"];
    [cell.contentView addSubview:testLabel];

    [theText release];
    [textField release];
    [testLabel release];

    return cell;        
} else {

    static NSString *CellIdentifier = @"Cell";
    CustomTableCell *cell = (CustomTableCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    [cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
    return cell; 
}


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

[tableView deselectRowAtIndexPath:indexPath animated:NO];   

selectedIndex = indexPath.row;
isSearching = YES;


[tableView beginUpdates];
[tableView endUpdates];

}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {        
if (isSearching && indexPath.row == selectedIndex) {
    return 110;
}
return rowHeight;           
} 

Il semble maintenant que la cellule est en expansion, mais pas réellement être actualisée afin de les étiquettes, et textfield arent. Ils ne montrent cependant quand je fais défiler la cellule et sur l'écran.

Des idées?

94voto

Pawel Points 2919

La Pomme façon de le faire est assez simple.

Tout d'abord, vous aurez besoin de sauvegarder l'indexPath ligne:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
   self.selectedRowIndex = [indexPath retain];
   [tableView beginUpdates];
   [tableView endUpdates];
}

Je vais vous expliquer le point de début/fin de la mise à jour de la partie plus tard.

Ensuite, lorsque vous avez sélectionné un index, vous pouvez dire à la tableView qu'il devrait donner à la ligne de plus d'espace.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
   //check if the index actually exists
   if(selectedRowIndex && indexPath.row == selectedRowIndex.row) {
        return 100;
   }
   return 44;
}

Ce sera le retour de hauteur 100 pour la cellule sélectionnée.

Maintenant, nous pouvons revenir au début/fin des mises à jour. Ce bloc déclenche le rechargement de tous les tableView de la géométrie. En outre, ce bloc est animé, ce qui finalement donne le impresions de la ligne en pleine expansion.

Espérons que cela a été utile, Pawel

5voto

TomSwift Points 22012

Pawel est beginUpdates/endUpdates astuce est bonne et j'utilise souvent. Mais dans ce cas, il vous suffit de recharger les lignes qui sont en train de changer d'état, de s'assurer que vous avez correctement les recharger avec le type de cellule désiré, et que vous renvoyer la bonne nouvelle hauteur de la cellule.

Ici, c'est un travail complet de la mise en œuvre de ce que je pense que vous essayez d'accomplir:

.h:

#import <UIKit/UIKit.h>

@interface ExpandingTableViewController : UITableViewController 
{

}

@property (retain) NSIndexPath* selectedIndexPath;

@end

.m:

@implementation ExpandingTableViewController
@synthesize selectedIndexPath;

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}


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

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

    static NSString *CellIdentifier1 = @"Cell1";
    static NSString *CellIdentifier2 = @"Cell2";

    UITableViewCell *cell;

    NSIndexPath* indexPathSelected = self.selectedIndexPath;

    if ( nil == indexPathSelected || [indexPathSelected compare: indexPath] != NSOrderedSame )
    {
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
        }

        cell.textLabel.text = [NSString stringWithFormat: @"cell %d", indexPath.row];
    }
    else
    {
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier2] autorelease];
        }

        cell.textLabel.text = [NSString stringWithFormat: @"cell %d", indexPath.row];
        cell.detailTextLabel.text = [NSString stringWithFormat: @"(expanded!)", indexPath.row];
    }

    return cell;
}

#pragma mark -
#pragma mark Table view delegate

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ( self.selectedIndexPath != nil && [self.selectedIndexPath compare: indexPath] == NSOrderedSame )
    {
        return tableView.rowHeight * 2;
    }

    return tableView.rowHeight;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    NSArray* toReload = [NSArray arrayWithObjects: indexPath, self.selectedIndexPath, nil];
    self.selectedIndexPath = indexPath;

    [tableView reloadRowsAtIndexPaths: toReload withRowAnimation: UITableViewRowAnimationMiddle];
}


#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
}

- (void)dealloc {
    [super dealloc];
}

@end

Si vous ne voulez pas de rechargement de la cellule (vous voulez garder votre cellule existante et il suffit de changer la taille, et probablement ajouter/supprimer certains sous-vues), puis simplement faire de beginUpdates/endUpdates truc dans didSelectRowAtIndexPath: et appeler une méthode sur votre cellulaire pour inciter le changement de présentation. beginUpdates/endUpdates invite le tableView à ré-interroger les hauteurs pour chaque cellule, alors assurez - vous de retourner la valeur correcte.

2voto

neha Points 2033

Créer une classe qui sous-classes UITableviewcell dans votre projet. Créer cette de la classe de plume et de l'ensemble de ses parent à la classe dans votre projet avec tableview et de remplacer son -

(void)setSelected:(BOOL)selected animated:(BOOL)animated 

Méthodes d'écriture contractCell() et expandCell() dans cette classe, et de fournir la hauteur des cellules que vous souhaitez dans expandCell méthode. Appelons cela des méthodes de manière appropriée en se basant sur certains indicateurs définis pour identifier météo la cellule est en état d'expansion ou de l'état contracté. Utilisez votre tableview de l'

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

méthode pour gérer la sélection de cellules.

0voto

Rajender Kumar Points 621

Remplacez votre fonction cellForRowAtIndexPath par celle-ci.

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

    if (isSearching && indexPath.row == selectedIndex) {

        static NSString *CellIdentifier = @"SearchCell";
       CustomTableCell *cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        [cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];

        UILabel *theText = [[UILabel alloc] initWithFrame:CGRectMake(10.0,
10.0, cell.contentView.bounds.size.width
-20, 22.0)];
        theText.text = @"Title Text";
        [cell.contentView addSubview:theText];


        UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 10 +
46.0, cell.contentView.bounds.size.width - 20, 40.0)];
        textField.borderStyle = UITextBorderStyleLine;
        [cell.contentView addSubview:textField];        

        UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0,
88.0, cell.contentView.bounds.size.width - 20, 22.0)];
        testLabel.text = [NSString stringWithFormat:@"Some text here"];
        [cell.contentView addSubview:testLabel];

        [theText release];
        [textField release];
        [testLabel release];

        return cell;        
    } else {

        static NSString *CellIdentifier = @"Cell";
        CustomTableCell *cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        [cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
        return cell; 
    }
    }
 

-1voto

mahendra Points 27

créer un tableau wof dictionnaire qui ont une clé Select_sts qui vaut 0 au début quand cliquer sur sa modification 1 accourding u change table

 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{

    customView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 40.0)];
    UILabel * headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    headerLabel.backgroundColor = [UIColor clearColor];
    headerLabel.opaque = NO;
    headerLabel.textColor = [UIColor blackColor];
    headerLabel.highlightedTextColor = [UIColor whiteColor];
    headerLabel.font = [UIFont boldSystemFontOfSize:16];
    headerLabel.frame = CGRectMake(5.0, 10.0, 300.0, 20.0);
    headerLabel.text=[NSString stringWithFormat: @"PNR %@",[[record objectAtIndex:section] objectForKey:@"number"]];
    customView.backgroundColor=[UIColor whiteColor];

btn_openClose.tag=section+10000;
    btn_openClose.backgroundColor=[UIColor clearColor];
    //  [btn_openClose setImage:[UIImage imageNamed:@"down_arrow.png"] forState:UIControlStateNormal];
    [btn_openClose addTarget:self action:@selector(collapseExpandButtonTap:) forControlEvents:UIControlEventTouchUpInside];
    [customView addSubview:btn_openClose];

}


- (void) collapseExpandButtonTap:(id) sender{
    int indexNo=[sender tag]-10000;
//    NSLog(@"total_record    %@",[total_record objectAtIndex:indexNo]);
    NSMutableDictionary *mutDictionary = [[total_record objectAtIndex:indexNo] mutableCopy];
   if([[mutDictionary objectForKey:@"Select_sts"] integerValue]==0)
       [mutDictionary setObject:[NSNumber numberWithInt:1] forKey:@"√"];
    else
       [mutDictionary setObject:[NSNumber numberWithInt:0] forKey:@"Select_sts"];

    [total_record replaceObjectAtIndex:indexNo withObject:mutDictionary];

//    [table_view beginUpdates];
//    [table_view reloadData];
//    [table_view endUpdates];

    NSMutableIndexSet *indetsetToUpdate = [[NSMutableIndexSet alloc]init];
    [indetsetToUpdate addIndex:indexNo]; // [indetsetToUpdate addIndex:<#(NSUInteger)#>]
    // You can add multiple indexes(sections) here.
    [table_view reloadSections:indetsetToUpdate withRowAnimation:UITableViewRowAnimationFade];

}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X