2010-07-21 10 views
1

Je suis un peu perplexe et j'espère que quelqu'un pourra m'aider. J'ai une liste de dictionnaires. J'essaie de le lire dans une table. Le plist ressemble à ceci:Accéder aux données d'un tableau de dictionnaires contenant un tableau

<array> 
    <dict> 
     <key>sectionTitle</key> 
     <string>A</string> 
     <key>rowData</key> 
     <array> 
      <dict> 
       <key>Title</key> 
       <string>Albert Author</string> 
       <key>dText</key> 
       <string>text for detail view</string> 
      </dict> 
      <dict> 
       <key>Title</key> 
       <string>Antony Author</string> 
       <key>dText</key> 
       <string>Descriptive text for detail view</string> 
      </dict> 
      <dict> 
       <key>Title</key> 
       <string>Azerifiel Author</string> 
       <key>dText</key> 
       <string>Text for detail view</string> 
      </dict> 
     </array> 
    </dict> 
    <dict> 
     <key>sectionTitle</key> 
     <string>B</string> 
     <key>rowData</key> 
     <array> 
      <dict> 
       <key>Title</key> 
       <string>Barny Author</string> 
       <key>dText</key> 
       <string>text for detail view</string> 
      </dict> 
      <dict> 
       <key>Title</key> 
       <string>Bazle Author</string> 
       <key>dText</key> 
       <string>text for detail view</string> 
      </dict> 
      <dict> 
       <key>Title</key> 
       <string>Bruno Author</string> 
       <key>dText</key> 
       <string>text for detail view</string> 
      </dict> 
     </array> 
    </dict> 
</array> 

Mon problème est le suivant: je peux faire une structure similaire moins les tableaux alimenter une vue de la table, mais je ne peux pas le code ci-dessus avec le travail de tableaux. Je ne suis pas sûr de savoir comment traiter les tableaux dans le code, mais je ne peux pas m'en débarrasser parce que je veux que la table finale soit indexée et sectionnée. Voici le code de ma méthode viewDidLoad.

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Path to the plist (in the application bundle) 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Tester" ofType:@"plist"]; 

    // Build the array from the plist 
    NSArray *dictArray = [[NSArray alloc] initWithContentsOfFile:path]; 
    NSMutableArray *mutableArray = [[NSMutableArray alloc] init]; 

    for(NSDictionary *dict in dictArray) 
    { 
     DictModel *term = [[DictModel alloc] init]; 
     term.sectionTitle = [dict objectForKey:@"sectionTitle"]; 
     term.Title = [dict objectForKey:@"Title"]; 
     term.dText = [dict objectForKey:@"dText"]; 
     [mutableArray addObject:term]; 
     [term release]; 
    } 

    tableDataSource = [[NSArray alloc] initWithArray:mutableArray]; 
    [mutableArray release]; 
    [dictArray release]; 
    [super viewDidLoad]; 
} 

J'ai une classe distincte appelée DictModel qui ressemble à ceci:

@interface DictModel : NSObject { 
    NSString *sectionTitle; 
    NSString *Title; 
    NSString *dText; 
} 

@property(nonatomic, retain) NSString *sectionTitle; 
@property(nonatomic,retain) NSString *Title; 
@property(nonatomic, retain) NSString *dText; 

@end 

Où vais-je tort? J'ai essayé d'importer les tableaux mais je n'ai pas pu le faire fonctionner. Je Figure que je ne comprends pas quelque chose quelque part. Les conseils sont très appréciés.

Voici ma cellule pour la méthode des lignes. Cela pourrait être l'endroit où le problème d'affichage est. J'ai ajouté ceci à la demande d'un comentator:

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

static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
            reuseIdentifier:CellIdentifier] autorelease]; 
} 

// Configure the cell. 
DictModel *term = [tableDataSource objectAtIndex:indexPath.row]; 
cell.textLabel.text = term.Title; 
cell.detailTextLabel.text = term.dText; 

return cell; 

}

+0

Alors, quel est le problème exactement? Avez-vous actuellement une erreur ou avez-vous besoin d'instructions sur la façon de générer votre plist dans un tableau indexé et groupé? –

+0

Ma table apparaît vide. Mais je sais que j'accède au plist ok parce qu'il va révéler la chaîne sectionTitle si je pointe la méthode rowAtIndex. en général, j'essaie de me faire une idée des plistes et de les commander/charger pour le moment. –

+0

Les méthodes de source de données de votre vue de table sont-elles appelées? – Ideveloper

Répondre

1

Je résolu ce problème il y a un peu de temps avec un peu d'aide des bonnes personnes ici et dans les forums Dev mac. Je pensais que je reviendrais et partagerai ce que j'ai appris pour quelqu'un d'autre qui est nouveau sur iPhone Dev (comme moi) et qui se bat avec ce problème.

NOTE S'IL VOUS PLAÎT:Ce qui suit est écrit au mieux de ma compréhension de ce que je l'ai appris à essayer de résoudre ce problème, donc il peut y avoir quelques erreurs techniques dans ma description. Si vous repérez un, je serais heureux si vous les signaler. Je suis engagé dans le développement de l'iphone parce que je veux apprendre à programmer, donc les corrections sont les bienvenues!

Tout d'abord, My Plist est toujours le même. C'est un tableau de dictionnaires. C'est vraiment une façon beaucoup plus simple de faire ce que je voulais faire que d'utiliser un Dictionary of Arrays qui est ce que j'ai commencé avec. La raison pour laquelle le code dans ma publication originale semble si mauvais est parce que c'était basé sur ma compréhension de la façon de remplir une table en utilisant un dictionnaire de tableaux, ce qui est maladroit.

Source des données traitées, passons à mon fichier .h. c'est assez simple et ressemble à ceci:

@interface MyTableViewController : UITableViewController 
{ 
IBOutlet UITableView *myTableView; 
MyDetailViewController *myDetailViewController; 
NSArray *tableDataSource; 

} 

@property (nonatomic, retain) myDetailViewController *myDetailViewController; 
@property (nonatomic, retain) NSArray *tableDataSource; 

@end 

Tout assez évident. J'ai mon point de vente pour ma vue de table et ma vue de détail de table. J'ai aussi un tableau que je vais lire .plist dans la table.

Déplacement sur mon fichier .m qui ressemble à ceci:

@implementation TableViewController 
@synthesize myDetailViewController; 
@synthesize tableDataSource; 

- (void)viewDidLoad { 
[super viewDidLoad]; 

self.title = NSLocalizedString(@"Tester", @"Browse by name"); 

// Path to the plist (in the application bundle) 
NSString *path = [[NSBundle mainBundle] pathForResource:@"Testers" ofType:@"plist"]; 

// Retrieve the plist's root element array 
NSArray *array = [[NSArray alloc] initWithContentsOfFile:path]; 

// Assign the plist array to my instance variable 
self.tableDataSource = array; 
[array release]; 
} 

Ayant ma première question à l'esprit, je suppose que la partie importante de se concentrer sur est la méthode viewDidLoad. Fondamentalement, après le super j'attribue le nom au haut de la vue de la table. Je crée ensuite une chaîne appelée 'path' qui est composée de mon .plist appelé "Testers". Je crée un tableau appelé 'array' et l'initialise avec le contenu de la chaîne que j'ai précédemment appelée 'path'. Enfin, j'assigne mon tableau .plist à ma variable d'instance NSArray 'tableDataSource'. C'est tellement plus simple que mon essai original.Pour une chose, je n'ai plus besoin du modèle de classe séparé.

La prochaine chose clé est mon cellForRowAtIndexPathMethod qui ressemble maintenant à ceci:

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

static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
            reuseIdentifier:CellIdentifier] autorelease]; 
} 

// Configure the cell. 
NSDictionary *sectionDictionary = [tableDataSource objectAtIndex:indexPath.section]; 
NSArray *sectionRowArray = [sectionDictionary objectForKey:@"rowData"]; 
NSDictionary *rowDictionary = [sectionRowArray objectAtIndex:indexPath.row]; 
cell.textLabel.text = [rowDictionary objectForKey:@"Title"]; 
return cell; 
} 

C'est presque le même que précédemment, sauf les moyens par lesquels la cellule est configuré a modifié pour accueillir ma nouvelle façon de lire les données du .plist. Donc, je ne me réfère plus au modèle Dict. "rowData" et "Title" sont des clés dans mon plist (voir tout en haut de la page). "rowData" est la clé pour chaque section et "Title" est le texte qui est visible dans la cellule lorsque le script est en cours d'exécution.

L'autre bit d'information clé est la méthode didSelectRowAtIndexPath, qui détermine ce qui est poussé dans la vue détaillée lorsqu'une cellule est sélectionnée. Il ressemble à ceci:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
//Get the dictionary of the selected data source. 
NSDictionary *dictionary = [[[self.tableDataSource objectAtIndex:indexPath.section]objectForKey:@"rowData"] objectAtIndex:indexPath.row]; 

MyDetailViewController *controller = [[MYDetailViewController alloc] initWithNibName:@"MyDetailView" bundle:[NSBundle mainBundle]]; 

controller.title = [dictionary objectForKey:@"Title"]; 
controller.dText = [dictionary objectForKey:@"dText"]; 

[self.navigationController pushViewController:controller animated:YES]; 

[controller release]; 

} 

Je commence par obtenir le dictionnaire pour la source de données de table qui a été attribué dans ma méthode de viewDidLoad à ma variable d'instance « tableDataSource ». Je dis alors à mon contrôleur de vue détail qu'il est nib dans le mainbundle et lui dis que quand la vue de détail est poussée il devrait mettre tout ce qui est dans la position de la clé "Titre" comme titre de cette instance particulière de la vue de détail devrait peupler le TextView dans cette plume avec le texte dans le .plist à la clé "dText".

Eh bien, c'est à peu près tout. Cela a bien fonctionné pour moi, même si je ne peux pas jurer que c'est la bonne façon de le faire. Grâce aux personnes qui m'ont aidé à l'obtenir, j'ai gravi une autre colline de taupes!

Espérons que cela soit utile à quelqu'un d'autre.

+0

Merci pour cette belle explication. J'étais coincé à lire le tableau de dictionnaires dans un autre dictionnaire. À votre santé! – nasaa

Questions connexes