UIAlertController с текстовым полем - нажатие кнопки возврата только скрывает клавиатуру, не выполняет действия?

Я пытаюсь использовать iOS 8 UIAlertController вместо того, где раньше использовал бы UIAlertView. Я хочу, чтобы пользователь мог ввести текст в это предупреждение и нажать "ОК" для обработки текста или "Отмена" для отмены.

Вот базовый код:

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Change Value" message:@"Enter your new value."];
[alert addTextFieldWithConfigurationHandler:nil];

[alert addAction: [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
    UITextField *textField = alert.textFields[0];
    NSLog(@"text was %@", textField.text);
}]];

[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
    NSLog(@"Cancel pressed");
}]];

[presentingVC presentViewController:alert animated:YES completion:nil];

Со старым UIAlertView я бы пометил его alertViewStyle UIAlertViewStylePlainTextInput. Затем, если пользователь нажал кнопку "Возврат" на клавиатуре после ввода текста, метод UIAlertViewDelegate willDismissWithButtonIndex: будет вызываться с некоторым buttonIndex (в зависимости от того, какие кнопки были указаны в UIAlertView).

В новом UIAlertController, если пользователь нажимает кнопки "ОК" или "Отмена", их соответствующие действия выполняются, как и ожидалось; но если пользователь просто нажимает клавишу "Возврат" на клавиатуре, он просто скрывает клавиатуру, но предупреждение остается на экране, и никаких действий не выполняется.

Я подумал о настройке текстового поля, чтобы установить UITextFieldDelegate в self, а затем, возможно, переопределить метод textFieldDidReturn:, но я также не знаю, есть ли способ вызвать один из UIAlertController программно. И в любом случае это звучит беспорядочно/хаки. Мне что-то не хватает?

Ответ 1

В iOS 9.3 это происходит, когда у вас есть несколько действий с стилем UIAlertActionStyleDefault.

Когда вы добавляете одно действие с UIAlertActionStyleDefault, а другое с UIAlertActionStyleCancel, действие со стилем по умолчанию будет называться

Ответ 2

Не идеальный ответ, но в итоге я извлек код действия в метод и просто вызвал этот метод как из действия, так и из метода textFieldDidReturn: в UITextFieldDelegate.

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];

    [self doAction:textField];
    [self dismissViewControllerAnimated:YES completion:NULL];

    return NO;
}

Ответ 3

Попробуйте это в iOS 8.0.2, возможно, оно исправлено. Мое текстовое поле запускает действие по умолчанию "ОК", даже не используя какое-либо делегирование.

Ответ 4

Решение Swift 3:

Убедитесь, что у вас есть только один параметр как .default. Я также выяснил, что такое же неправильное поведение возникает при использовании одного параметра .default и одного .destructive... не знаю, почему это происходит.

let cancelAction = UIAlertAction(title: "Discard", style: .cancel) { (_) -> Void in
            self.invokedPullToAdd = false
        }
let submitAction = UIAlertAction(title: "Save", style: .default) { [unowned ac] _ in
            let answer = ac.textFields![0]
            if answer.text != "" {
                self.addItem(name: answer.text!)
                self.tableView.reloadData()
            } else {
                print ("WARNING: No input!")
            }
            self.invokedPullToAdd = false
        }

Ответ 5

Вы не должны устанавливать два "UIAlertActionStyleCancel" в UIAlertAction.