30 votes

Ajout d'un nombre inconnu de lignes à UITableView «Cellules statiques»

J'ai un tableau statique créé dans Interface Builder avec 6 sections avec différentes quantités de lignes. Maintenant, je veux ajouter un 7ème section avec un nombre variable de lignes.

Tout d'abord, dès que j'ai décommentez la table standard délégué méthodes qui sont insérés par Xcode, je reçois un accident d'auto.tableView.tableHeaderView = containerView; où j'ai ajouté un en-tête de la table.

Plus important, je suis un crash avec le code suivant

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 7;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section==6) {
        return 4;
    } else {
        return [super tableView:tableView numberOfRowsInSection:section];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{/*
    if (indexPath.section == 6) {
        static NSString *CellIdentifier = @"cellWireless";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        // Configure the cell...

        return cell;
    }*/
    return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}

Comment puis-je correctement laisser les sections comme elles sont, mais ajouter une supplémentaire avec quelques cellules?

40voto

Darren Points 3714

Pour ajouter des cellules dynamiques à une table de cellules statiques, vous devez remplacer chaque méthode déléguée UITableView qui a un indexPath.

 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
-(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath

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

.

 -(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
     return NO;
}

-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{     
     return NO;
}

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{     
     return UITableViewCellEditingStyleNone;     
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
     int section = indexPath.section;

     // if dynamic section make all rows the same height as row 0
     if (section == self.dynamicSection) {
          return [super tableView:tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
     } else {
          return [super tableView:tableView heightForRowAtIndexPath:indexPath];
     }
}

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
     int section = indexPath.section;

     // if dynamic section make all rows the same indentation level as row 0
     if (section == self.dynamicSection) {
          return [super tableView:tableView indentationLevelForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
     } else {
          return [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath];
     }
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     if (section == self.dynamicSection ) {
          return [self.dataListArray count];
     } else {
          return [super tableView:tableView numberOfRowsInSection:section];
     }
}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
     int section = indexPath.section;
     int row = indexPath.row;


     if (section == self.dynamicSection) {
          // make dynamic row's cell
          static NSString *CellIdentifier = @"Dynamic Cell";
          UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

          if (!cell) {
               cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
          }

          cell.textLabel.text = [self.dataListArray objectAtIndex:row];
          return cell;
    } else {
          return [super tableView:tableView cellForRowAtIndexPath:indexPath];
    }
}
 

Ce n'est qu'une fois que vous aurez remplacé chaque méthode que votre table commencera à fonctionner. Pour toute référence à la section statique, référez-vous simplement à [super].

8voto

JasonD Points 2117

Darren réponse m'a donné l'idée de ce qui a fonctionné pour moi, mais je n'ai pas eu à aller aussi loin que de mettre en œuvre tous les tableView délégué de la méthode. Vous avez vraiment besoin de remplacer numberOfRowsInSection et cellForRowAtIndexPath.

J'ai d'abord défini un tableau statique dans Interface Builder, 4 sections, de 2 à 4 cellules par section. Je voulais section 0, 2 et 3, de la statique et de regarder exactement comme ils l'ont fait au bureau de l'IB, mais je voulais la section 1 ont une coutume nombre de lignes avec un affichage personnalisé dans chaque cellule basée sur un tableau de valeurs que j'ai eu.

De l'avis du contrôleur de la table statique, remplacer le nombre de cellules retourné pour votre section dynamique, mais accepter les valeurs par défaut pour toutes les autres sections (ils vont revenir à l'IB valeurs). Faire de même pour cellForRowAtIndexPath et le retour de la [super] la mise en œuvre de toutes les sections à l'exception de l'article 1.

@implementation myMostlyStaticTableViewController
@synthesize myFancyArray;

- (NSInteger) tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger) section
{
    if (section == 1)
        return [myFancyArray count]; // the number of rows in section 1
    else
        return [super tableView:tableView numberOfRowsInSection:section];
}

- (UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
{
    // for cells not in section 1, rely on the IB definition of the cell
    if (indexPath.section != 1)
        return [super tableView:tableView cellForRowAtIndexPath:indexPath];

    // configure a task status cell for section 1
    MyCustomTableViewCell *cell;
    cell = [tableView dequeueReusableCellWithIdentifier:@"myCustomCell"];
    if (!cell)
    {
        // create a cell
        cell = [[MyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"myCustomCell"];
    }
    cell.myCustomLabel.text = [myFancyArray objectAtIndex:indexPath.row];
    return cell;
}
@end

Et bien sûr, vous avez besoin d'une cellule personnalisé:

@implementation MyCustomTableViewCell

- (UITableViewCell *) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    // initialize cell and add observers
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (!self)
        return self;
    self.clipsToBounds = YES;
    self.selectionStyle = UITableViewCellSelectionStyleNone;

    // configure up some interesting display properties inside the cell
    _label = [[UILabel alloc] initWithFrame:CGRectMake(20, 9, 147, 26)];
    _label.font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:17];
    _label.textColor = [UIColor colorWithWhite:0.2 alpha:1];
    [self.contentView addSubview:_label];

    return self;
}

@end

3voto

cocoanut Points 2396

Je pensais que j'ajouterais une réponse mise à jour basée sur l'excellente réponse de @ Darren. La plupart des méthodes de délégué ne sont pas requises. Donc, je viens d'ajouter ceux requis. Vous pouvez facilement ajouter une cellule personnalisée si vous le souhaitez, même en utilisant un fichier nib. L'image montre un tableau statique avec 3 sections. La dernière section est dynamique au moment de l'exécution. C'est extrêmement pratique. Cela fonctionne dans ios7 BTW.

entrez la description de l'image ici

 #define DYNAMIC_SECTION 2

#import "MyTableViewController.h"

@interface MyTableViewController ()
@property (strong, nonatomic)NSArray *myArray;
@end

@implementation MyTableViewController

- (id)initWithCoder:(NSCoder *)aDecoder
    {
        if (self = [super initWithCoder:aDecoder]) {
            _myArray = @[@"ONE", @"TWO", @"THREE", @"FOUR"];
        }
        return self;
    }

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return [super numberOfSectionsInTableView:tableView];
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        if (section != DYNAMIC_SECTION) {
            return [super tableView:tableView numberOfRowsInSection:section];
        }
        return [self.myArray count];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.section != DYNAMIC_SECTION) {
            return [super tableView:tableView cellForRowAtIndexPath:indexPath];
        }
        static NSString *id = @"MyCell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:id];
        if (!cell) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:id];
        }
        cell.textLabel.text = self.myArray[indexPath.row];
        return cell;
    }

        // required
    -(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        int section = indexPath.section;
        if (section == DYNAMIC_SECTION) {
            return [super tableView:tableView indentationLevelForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
        } else {
            return [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath];
        }
    }

            // Not required
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        if (section != DYNAMIC_SECTION) {
            return [super tableView:tableView titleForHeaderInSection:section];
        }
        return @"some title";
    }
 

0voto

Johnny Gamez Points 99

Je pense que vous allez devoir rendre votre UITableView dynamique. Étant donné que vous avez un nombre de lignes "inconnu", vous définirez probablement la méthode déléguée sur quelque chose comme ceci:

  - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [someArray count];
}
 

0voto

StuFF mc Points 1146

J'ai découvert quelque chose d'assez intéressant, je pense, et c'est plus la peine de répondre qu'un "commentaire". J'ai eu cette statique tableView avec des lignes dynamiques de travail, puis il a cessé de travailler. La raison en est simple. J'ai déjà eu

[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]

et plus tard décidé que je voulais/besoin d'une Cellule Personnalisé que j'avais de la conception dans mon StoryBoard et seulement définir le point de vente à mon UITableView sous-classe. J'ai donc utilisé une autre technique

[super tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.section]];

Ici, le problème semble être que cette cellule devient réutilisés et donc vous ne pourrez voir l'une des cellules à la fois. Parfois, vous aurez même de n'en voir aucun, ils vont tous être vide! Si vous faites défiler pour voir apparaître les autres cellules du peu de temps qui apparaît alors en voie de disparition (de plus, comme le vacillement!).

Cela m'a conduit au sérieux les noix, jusqu'à ce que j'ai réalisé ce qui est (im)possible. En outre, ne pas essayer de faire

[super.tableView dequeueReusableCellWithIdentifier:CellIdentifier]

parce que, comme mentionné par d'autres personnes ce sont toujours les retours nil statique tableView.

---

Donc, je ne suis pas sûr que faire. Je crois que je vais utiliser le "statique prototypes de route", qui se compose de

  • À l'aide d'un Prototype de la Vue de la Table avec les Identificateurs de Cellules comme le "31" pour la Section 3 de la Ligne 1. Je peux alors faire quelque chose comme
NSString *identificateur = [NSString stringWithFormat:@"%d%d", indexPath.section, indexPath.ligne];
cellule = [tableView dequeueReusableCellWithIdentifier:identificateur];
  • Utilisation Prototype de Cellules ainsi que pour les en-Têtes. J'utilise "Cell1-Header" pour la Cellule de l'Identificateur de l'en-tête de la section 1 et puis avoir quelque chose comme
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
 NSString *identificateur = [NSString stringWithFormat:@Cellule"%d en-Tête", section];
 UITableViewCell *cellule = [tableView dequeueReusableCellWithIdentifier:identificateur];
 de retour de la cellule.contentView;
}

La première chose à prendre ici, c'est que vous pouvez toujours commence avec un statique tableView, mais le moment où vous réalisez que vous allez besoin de quelque chose de dynamique, en échange de Prototype (garder vos lignes, bien que je ne me souviens pas de ce qu'il fait avec les sections!) et utiliser ce BAISER technique.

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