2010-11-03 6 views
0

J'essaie de créer une interface utilisateur afin que l'utilisateur puisse modifier les attributs d'une entité de données principale. Lorsque l'utilisateur appuie sur le bouton d'édition, la sélection d'une ligne va appuyer sur listDetailViewController, qui est juste une vue de table qui affiche les attributs. Il utilise une cellule de vue de table personnalisée avec une étiquette et un UITextField. Le listDetailViewController affiche les attributs correctement, et acceptera le texte comme il est censé le faire, mais je ne peux pas comprendre comment obtenir le texte saisi par l'utilisateur à enregistrer.Impossible d'enregistrer les modifications apportées aux attributs de données de base

Si je ne m'explique pas clairement, voici un exemple. Je veux changer le nom de la liste, donc je tape Modifier, touchez la liste, appuyez sur la ligne Nom de la liste, le clavier apparaît, je tape le nouveau nom, appuyez sur Terminé et il me renvoie à la RVC sans aucun des changements enregistré. Je me suis cogné la tête pendant quelques jours et j'adorerais de l'aide!

Voici le code correspondant de ListDetailViewController:

- (void)viewDidLoad { 
[super viewDidLoad]; 
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] 
           initWithBarButtonSystemItem:UIBarButtonSystemItemDone 
           target:self 
           action:@selector(done)]; 
self.navigationItem.rightBarButtonItem = doneButton; 
[doneButton release]; 

self.tableView.allowsSelection = NO; 
self.tableView.allowsSelectionDuringEditing = NO; 
} 



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


// Customize the appearance of table view cells. 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
static NSString *DetailCellIdentifier = @"DetailCell"; 

ListDetailCell *cell = (ListDetailCell *)[tableView dequeueReusableCellWithIdentifier:DetailCellIdentifier]; 
if (cell == nil) { 
    [[NSBundle mainBundle] loadNibNamed:@"ListDetailCell" owner:self options:nil]; 
    cell = listDetailCell; 
    self.listDetailCell = nil; 

// Configure the cell... 

    // list name 
    if (0 == indexPath.row) { 
     cell.label.text = @"List Name"; 
     cell.textField.text = self.selectedList.listName; 
     cell.textField.placeholder = @"Name"; 
    } 

    // Detail 1 
    if (1 == indexPath.row) { 
     cell.label.text = @"Detail 1"; 
     cell.textField.text = selectedList.detail1; 
     cell.textField.placeholder = @"Detail 1"; 
    } 

    // Detail 2 
    if (2 == indexPath.row) { 
     cell.label.text = @"Detail 2"; 
     cell.textField.text = selectedList.detail2; 
     cell.textField.placeholder = @"Detail 2"; 
    } 
} 

return cell; 
} 


- (void)done { 
[self.listDetailCell resignFirstResponder]; 
[self.navigationController popViewControllerAnimated:YES]; 
} 

Les Ivars label et textField sont déclarés dans ListDetailCell, qui est la pointe de la cellule de tableau je l'ai mentionné plus tôt.

Répondre

3

Je ne sais pas si votre problème est correct ou si ma réponse est la meilleure, mais c'est ce que j'ai fait récemment. J'ai un TableViewController et UITableView qui affichent une série de cellules personnalisées pour éditer des données. Ceci reproduit fondamentalement ce que j'ai vu un certain nombre d'autres applications faire pour créer des écrans d'édition de données.

Chacune des cellules personnalisées possède un UITextField. Lorsque l'utilisateur termine l'édition d'une cellule, UITextField déclenche un message à UITextFieldDelegate. J'ai donc ajouté le protocole UITextFieldDelegate à TableViewController et lors de la configuration de la cellule personnalisée dans cellForRowAtIndexPath, j'ai défini TableViewController comme délégué UITextFields. Ensuite, lorsque l'utilisateur a terminé l'édition, le message d'édition de fin est envoyé et je peux ensuite obtenir la valeur de l'UITextField et la stocker dans l'objet entité gérée. Je m'excuse, mais je n'ai pas accès à mon code pour le moment ou je vais copier et coller un exemple pour vous.

Quoi qu'il en soit, certaines choses à surveiller:

  • Dans le code pour le message de délégué vous devez d'abord identifier le UITextField qui a déclenché l'appel. La meilleure façon de procéder consiste à définir la propriété Tag sur UITextField lorsque vous créez le UITableCell qui le contient. Ensuite, dans la méthode déléguée, vous pouvez utiliser une instruction switch pour sélectionner le champ d'entité dans lequel stocker la valeur.

  • L'utilisation du clavier lorsqu'un utilisateur appuie sur une zone non modifiable d'UITableView peut s'avérer difficile. Vous devez stocker une liste d'objets qui peuvent avoir un clavier, et quand un clic se produit, passez-les en boucle et faites le premier répondeur pour retirer le clavier de l'affichage. Si vous appuyez sur un bouton de sauvegarde de la barre de navigation ou sur autre chose en dehors de UITableView, le clavier ne sera pas supprimé ou le premier répondeur supprimé, le délégué du champ en cours d'édition n'est donc pas appelé. Vous devez ajouter du code pour déclencher la séquence de sauvegarde.

  • Si vous avez des UITextView, ils utilisent un délégué différent.

Pour ajouter le délégué, vous aurez besoin de faire quelque chose comme ceci (extrait de votre code ci-dessus):

@interface MyTableViewController : UITableViewController <UITextFieldDelegate> 

.... 

    if (0 == indexPath.row) { 
     cell.label.text = @"List Name"; 
     cell.textField.text = self.selectedList.listName; 
     cell.textField.placeholder = @"Name"; 

     cell.textField.delegate = self; // Setting controller as text field delegate. 
     cell.textField.tag = 1; // Really should use an enum here for clarity. 

    } 

.... 

-(void) textFieldDidEndEditing:(UITextField *) textField { 
    switch(textField.tag) { 
     case 1: //Again with the enum. 
      // Save field 1. 
      entity.someProperty = textField.text; 
     .... 
    } 
} 

Ceci est pour traiter un certain nombre de champs de texte. Une autre solution que j'ai trouvée consistait à stocker les valeurs modifiées dans un dictionnaire et à ne mettre à jour l'entité que lorsque l'utilisateur appuie sur Enregistrer. Avec ma solution ci-dessus, vous devrez également réinitialiser les propriétés des entités si l'utilisateur annule. Donc c'est cheval pour les cours.

+0

Dois-je ajouter le délégué à la classe de cellule ou à la méthode 'cellForRowAtIndexPath'? Et le clavier n'est pas un problème, puisque le bouton Terminé et le contrôleur de navigation fonctionnent comme ils sont supposés le faire. J'ai modifié mon exemple pour plus de clarté afin d'être plus clair! –

+0

J'ai mis à jour ci-dessus pour inclure un exemple de code. Méfiez-vous des fautes de frappe, je l'ai tapé à la main :-) – drekka

+0

Cela l'a fait, merci! J'enveloppe toujours mon cerveau autour des délégués, et chaque nouveau bit aide. :) –

Questions connexes