2010-10-31 5 views
13

Je suis sûr que cela est dans la documentation Apple ou doit avoir été répondu quelque part sur ce forum, car il semble si basique, mais je ne pouvais pas le trouver ni une solution particulièrement élégante moi-même.Stocker le contenu de UITextField avant que la vue n'apparaisse

Ce que j'ai est un UIViewController qui pousse une vue d'édition sur sa pile de navigation. La vue d'édition contient un tas de UITextFields. Si l'un d'eux est en cours de modification lorsque le bouton Précédent est touché, la méthode ViewWillAppear de la vue d'origine est appelée avant les méthodes de délégation UITextField de textFieldShouldEndEditing ou textFieldDidEndEditing ou la méthode d'action liée IB IB textFieldEditingEnded est appelée.

Voici un code qui, je l'espère le rendre plus clair:

Dans le UIViewController:

- (void) viewWillAppear: (BOOL) animated { 
    [super viewWillAppear: animated]; 
    NSLog(@"Entering view will appear for master view"); 
    nameLabelField.text = objectToEdit.name; 
} 
- (IBAction) editMyObject: (id) sender { 
    NSLog(@"Editing the object"); 
    EditViewController *evc = [[EditViewController alloc] initWithNibName: @"EditTableView" bundle: nil]; 
    evc.editedObject = objectToEdit; 
    [self.navigationController pushViewController: evc animated: YES]; 
    [evc release]; 
} 

Dans le EditViewController < UITextFieldDelegate>:

- (void) viewWillAppear: (BOOL) animated { 
    [super viewWillAppear: animated]; 
    nameField.text = editedObject.name; 
} 
- (void) viewWillDisappear: (BOOL) animated { 
    [super viewWillDisappear: animated]; 
    NSLog(@"In viewWillDisappear"); 
    if([self.navigationController.viewControllers indexOfObject: self] == NSNotFound) { 
     NSLog(@"-- We are not in controller stack... the back button has been pushed"); 
    } 
} 
- (BOOL) textFieldShouldEndEditing: (UITextField *) textField { 
    NSLog(@"In textFieldShouldEndEditing"); 
    // Store text field value here??? 
    // editedObject.name = nameField.text; 
    return YES; 
} 
- (void) textFieldDidEndEditing: (UITextField *) textField { 
    NSLog(@"In textFieldDidEndEditing"); 
    // Store text field value here??? 
    // editedObject.name = nameField.text; 
} 
- (IBAction) textFieldEditingEnded: (id) sender { 
    NSLog(@"In textFieldEditingEnded"); 
    // Store text field value here??? 
    // editedObject.name = nameField.text; 
} 

Le journal se termine par :

[...] Entrer vue apparaît pour une vue maître
[...] Modification de l'objet
[...] Dans viewWillDisappear
[...] - Nous ne sommes pas dans la pile de contrôleur .. . le bouton de retour a été poussé
[...] Entrer vue apparaît pour une vue maître
[...] Dans textFieldShouldEndEditing
[...] Dans textFieldEditingEnded
[...] Dans textFieldDidEndEditing

Je veux définir self.editedObject.name = nameField.text avant que l'étiquette ne soit définie dans viewWillAppear pour le UIViewController. J'ai pensé à la méthode viewWillDisappear pour le contrôle EditViewController pour voir si l'un de mes champs texte est actuellement le premier répondeur et si oui, obtenir leur texte et le stocker, mais cela ressemble à un tel kludge qui sera une douleur à maintenir si j'ajoute ou modifie des champs de texte.

Je peux également implémenter l'action textFieldEditingChanged IB liée pour définir le texte dans l'objet édité après chaque frappe, mais c'est aussi un peu de surcharge puisque je dois déterminer quel champ de texte je suis à chaque frappe (rappelez-vous seulement montré name mais il y a tout un tas d'entre eux). Tout ce dont j'ai besoin, c'est que l'édition soit terminée ou que l'édition soit terminée avant que viewWillAppear soit appelé dans UIViewController afin que nameFieldLabel soit correctement défini.

Répondre

17

OK, je compris une solution simple après beaucoup de navigation sur le Web, la lecture du forum et la lecture manuelle. C'était, comme je le soupçonnais, très simple, une seule ligne de code ajoutée. Dans la méthode viewWillDisappear du EditViewContorller j'ai simplement ajouté:

[self.view.window endEditing: YES]; 

Maintenant textFieldShouldEndEditing, textFieldEditingEnded et textFieldDidEndEditing tous se décocha un tir avant la viewWillAppear de la vue principale fait.

Alors maintenant, la méthode viewWillDisappear ressemble:

- (void) viewWillDisappear: (BOOL) animated { 
    [super viewWillDisappear: animated]; 
    NSLog(@"In viewWillDisappear"); 
    // Force any text fields that might be being edited to end so the text is stored 
    [self.view.window endEditing: YES]; 
} 

Et les méthodes déjà en place pour gérer le « retour » sur le clavier également en charge le bouton « Retour » sur le contrôleur de navigation. Merci Aaron et Jeff pour votre aide et m'aider à y réfléchir.

+0

Merci pour votre réponse. Je l'ai trouvé aussi être la réponse à cette question: http://stackoverflow.com/questions/11319144/ios-xcode-crashed-after-typing-in-texts-in-uitextfield-and-go-back-nsisobject/ 11364617 # 11364617 – zekel

+0

Merci beaucoup! Cela me rendait fou. Intuitivement, je voudrais voir cela comme le comportement par défaut. – guptron

+0

Cela ne fonctionne pas pour moi, la segue se passe avant 'viewWillDisappear': ( – RnMss

0

Pourquoi ne pas simplement créer votre propre bouton Précédent avec cette logique dans sa méthode d'action?

+0

Merci pour la suggestion Jeff. C'est peut-être ce que je dois faire, mais je perds l'interface utilisateur du bouton avec l'extrémité pointue, sauf si je fais beaucoup de travail en créant un fichier PNG, etc., etc. Je suis prêt à le faire si je dois, afin d'obtenir la fonctionnalité, mais j'espère que quelque chose me manque pour ajouter à mon code. – LavaSlider

-1

Je pense que d'un point de vue UX, vous devriez afficher une alerte pour déterminer si l'utilisateur veut annuler l'action d'édition qu'ils étaient au milieu de avant de quitter la vue actuelle. En alertant l'utilisateur, vous pouvez voir s'il a frappé le bouton par accident ou s'il a décidé de quitter la vue, prenez les mesures appropriées.

// add this to the field(s) to be edited, selector will be called as the changes 
// are being made... still difficult to handle a cancel, but should work 
[objectToEdit addTarget:self action:@selector(updateNameField:) 
         forControlEvents:UIControlEventEditingChanged]; 

code supplémentaire ici ...

// the method called to update object from parent view 
- (void)updateNameField:(id)sender { 
    <OBJECT TO UPDATE>.text = ((UITextField *)sender).text; 
} 
+0

Je serais d'accord avec ça. Je pensais vraiment que ce serait un bouton de retour intentionnel ... pourquoi devoir appuyer sur Done puis sur Back? Je suppose que l'exigence qui exclut les "Back" accidentels. Mais cela ne fournit aucune aide puisque je n'ai pas le moyen de savoir si je dois présenter l'alerte puisque je ne sais pas quoi ou si un champ de texte est en cours de modification. – LavaSlider

+0

@LavaSlider voir les éditions, pour faire quelque chose comme textFieldEditingChanged vous discutiez –

+0

@LavaSlider pas trop difficile d'implémenter quelque chose comme textFieldEditingChanged. Voir les modifications ci-dessus pour la solution –

Questions connexes