2010-04-17 10 views
6

In una sottoclasse UITableViewController, ci sono alcuni metodi che devono essere attuate al fine di caricare i dati e gestire l'evento di selezione fila:È possibile utilizzare NSDictionary con TableView su iPhone?

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; //there is only one section needed for my table view 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {    
    return [myList count]; //myList is a NSDictionary already populated in viewDidLoad method 
} 

- (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 ]; 
    } 

    // indexPath.row returns an integer index, 
    // but myList uses keys that are not integer, 
    // I don't know how I can retrieve the value and assign it to the cell.textLabel.text 


    return cell; 
} 


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

    // Handle row on select event, 
    // but indexPath.row only returns the index, 
    // not a key of the myList NSDictionary, 
    // this prevents me from knowing which row is selected 


} 

come dovrebbe NSDictionary di lavorare con TableView?

Qual è il modo più semplice per ottenere questo risultato?

risposta

23

Non capisco perché si desidera utilizzare un dizionario (che è ereditato in modo non ordinato) per un'attività che richiede risposte a domande ordinate (righe), ma suppongo che tu abbia già un dizionario da qualche parte e non possa cambiarlo . In questo caso, è necessario definire un ordine in cui si desidera visualizzare le chiavi, derivando in tal modo una matrice implicitamente. Un modo per farlo è in ordine alfabetico ordinare un altro è la seguente:

// a) get an array of all the keys in your dictionary 
NSArray* allKeys = [myList allKeys]; 
// b) optionally sort them with a sort descrriptor (not shown) 
// c) get to the value at the row index 
id value = [myList objectForKey:[allKeys objectAtIndex:indexPath.row]]; 

valore è ora l'oggetto selezionato, nel caso di tableView: didSelectRowAtIndexPath: o l'oggetto che vi serve per una trasformazione delle cellule in tableView: cellForRowAtIndexPath:

Se il NSDictionary sottostante cambia, è necessario ricaricare ([myTable reload] o simile) UITableView.

+0

La tua soluzione è abbastanza semplice per me. – bobo

+0

Soluzione semplice ma questo mi ha aiutato molto! – stitz

3

Sì. Ecco come l'abbiamo fatto:

Nel nostro parser XML abbiamo questo metodo che carica l'XML in un dizionario chiamato dict:

-(NSDictionary *)getNodeDictionary:(Node *)node { 
    if (node->level == 0) return xmlData; 
    else { 
     NSDictionary *dict = xmlData; 
     for(int i=0;i<node->level;i++) { 
      if ([[dict allKeys] containsObject:SUBNODE_KEY]) 
       dict = [[dict objectForKey:SUBNODE_KEY] objectAtIndex:*(node->branches+i)]; 
     } 
     return dict; 
    } 
} 

E questo metodo

-(NSDictionary *)getDataForNode:(Node *)node { 
NSDictionary* dict = [[self getNodeDictionary:node] copy]; 
return dict; 

}

Nella classe RadioData abbiamo una variabile di istanza:

Node *rootNode; 

e un gruppo di metodi

-(Node *)getSubNodesForNode:(Node *)node; 
-(Node *)getSubNodeForNode:(Node *)node atBranch:(NSInteger)branch; 
-(Node *)getParentNodeForNode:(Node *)node; 
-(NSInteger)getSubNodeCountForNode:(Node *)node; 
-(NSDictionary *)getDataForNode:(Node *)node; 

e una proprietà

@property (nonatomic) Node *rootNode; 

Infine nella ViewController quando INIT telaio usiamo:

radioData = data; 
curNode = data.rootNode; 

e all'interno cellForRowAtIndexPath abbiamo:

Node* sub = [radioData getSubNodeForNode:curNode atBranch:indexPath.row]; 
NSDictionary* dets = [radioData getDataForNode:sub];  

e in didSelectRowAtIndexPath:

Node* node = [radioData getSubNodeForNode:curNode atBranch:indexPath.row]; 
NSDictionary* data = [radioData getDataForNode:node]; 

Questo è probabilmente più di quanto si voleva, ma questo è il quadro generale.

+0

Grazie mille per la tua soluzione. Ma è complicato per me. – bobo

+0

Sì ... è un po 'complesso ma l'esempio è da un'app piuttosto complessa. Sfortunatamente, non ho un esempio più semplice a portata di mano. Questo dovrebbe, tuttavia, darti un punto di partenza. Forse usare gli array potrebbe essere più facile. –

Problemi correlati