Pergunta

Tenho certeza de que isso está na documentação da Apple ou deve ter sido respondido em algum lugar deste fórum, pois parece tão básico, mas eu não consegui encontrá -lo nem uma solução particularmente elegante.

O que eu tenho é um UIViewController que empurra uma visão de edição em sua pilha de navegação. A visualização de edição tem um monte de UITEXTFields. Se um deles está sendo editando quando o botão traseiro é tocado, o método ViewWillappear da vista original é chamado antes dos métodos de delegados de Uitextfield textFieldShouldEndEditing ou textFieldDidEndEditing, ou a ação ligada ao IB textFieldEditingEnded o método são chamados.

Aqui está algum código que espero que deixe mais claro:

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

No editViewControlleru003CUITextFieldDelegate> :

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

O log acaba com:

...] Entrar a visualização aparecerá para a Mestre View
...] editando o objeto
...] em vista
...] - Não estamos na pilha do controlador ... o botão de volta foi empurrado
...] Entrar a visualização aparecerá para a Mestre View
...] em Textfieldswoudingiting
...] em TextFielditingEdend
...] em TextFieldDendediting

Eu quero definir self.editedObject.name = nameField.text Antes que o rótulo seja colocado em viewWillAppear para o uiviewController.

Eu pensei no método ViewwillDisappear para o editViewController verificando se algum dos meus campos de texto é atualmente o socorrista e, se assim for, recebendo seu texto e armazenando -o, mas isso parece um kludge que será uma dor para manter se eu Adicione ou altere os campos de texto.

Eu também posso implementar o textFieldEditingChanged A ação vinculada ao IB para definir o texto no objeto editado após cada pressionamento de tecla, mas isso também é um pouco de sobrecarga, já que tenho que descobrir qual campo de texto estou em cada pressionamento (lembre -se de que só mostrei name Mas há um monte deles).

Tudo o que preciso é que a edição seja encerrada ou saiba que a edição será encerrada antes que o ViewWillappear seja chamado no UIViewController, para que o NameFieldLabel seja definido corretamente.

Foi útil?

Solução

Ok, eu descobri uma solução simples após muita sobrevivência na web, leitura do fórum e leitura manual. Era, como eu suspeitava, muito simples, apenas uma linha de código adicionada. No viewWillDisappear Método do EditViewContorller, eu simplesmente adicionei:

    [self.view.window endEditing: YES];

Agora textFieldShouldEndEditing, textFieldEditingEnded, e textFieldDidEndEditing todos são demitidos antes do viewWillAppear da visão mestre faz.

Então agora o viewWillDisappear Método se parece:

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

E os métodos já existentes para lidar com o 'retorno' no teclado também lidam com o botão 'traseiro' no controlador de navegação.

Obrigado Aaron e Jeff por sua ajuda e me ajudando a pensar isso.

Outras dicas

Por que não criar seu próprio botão de volta com essa lógica em seu método de ação?

Eu pensaria que, de uma perspectiva UX, você deve exibir um alerta para determinar se o usuário deseja cancelar a ação de edição que eles estavam no meio de antes de sair da visualização atual.

Ao alertar o usuário, você pode ver se eles pressionam o botão por acidente ou se decidiram deixar a visualização, tome a ação apropriada.

// 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];

código adicional aqui ...

// the method called to update object from parent view
- (void)updateNameField:(id)sender {
    <OBJECT TO UPDATE>.text = ((UITextField *)sender).text;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top