Какой простой способ получить всплывающее диалоговое окно ввода текста на iPhone


126

Я хочу получить имя пользователя. Простое диалоговое окно для ввода текста. Любой простой способ сделать это?


1
просто подождите несколько месяцев, примерно до сентября, и ваша жизнь станет намного проще.
Джонатан.

Ответы:


264

В iOS 5 для этого есть новый и простой способ. Я не уверен, что реализация полностью завершена, поскольку она не такая приятная, как, скажем, a UITableViewCell, но она определенно должна помочь, поскольку теперь она стандартно поддерживается в iOS API. Для этого вам не понадобится частный API.

UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"This is an example alert!" delegate:self cancelButtonTitle:@"Hide" otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
[alert release];

Это отображает alertView следующим образом (снимок экрана, сделанный из симулятора iPhone 5.0 в XCode 4.2):

пример предупреждения с параметром alertViewStyle, равным UIAlertViewStylePlainTextInput

При нажатии любых кнопок будут вызваны обычные методы делегата, и вы можете извлечь там textInput следующим образом:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 
    NSLog(@"Entered: %@",[[alertView textFieldAtIndex:0] text]);
}

Здесь я просто NSLog введенных результатов. В производственном коде вам, вероятно, следует сохранить указатель на свой alertView как глобальную переменную или использовать тег alertView, чтобы проверить, была ли функция делегата вызвана соответствующим, UIAlertViewно для этого примера это должно быть нормально.

Вы должны проверить API UIAlertView, и вы увидите, что определены еще несколько стилей.

Надеюсь, это помогло!

-- РЕДАКТИРОВАТЬ --

Я немного поигрался с alertView, и я полагаю, что не нужно объявлять, что вполне возможно редактировать textField по своему желанию: вы можете создать ссылку на объект UITextFieldи отредактировать его как обычно (программно). Сделав это, я создал alertView, как вы указали в своем исходном вопросе. Лучше поздно чем никогда, правильно :-)?

UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Hello!" message:@"Please enter your name:" delegate:self cancelButtonTitle:@"Continue" otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField * alertTextField = [alert textFieldAtIndex:0];
alertTextField.keyboardType = UIKeyboardTypeNumberPad;
alertTextField.placeholder = @"Enter your name";
[alert show];
[alert release];

Это вызывает это предупреждение:

UIAlertView, который использует alertStyle UIAlertViewPlainTextInput для запроса имени пользователя.

Вы можете использовать тот же метод делегата, что и я ранее, для обработки результата ввода. Я не уверен, что вы можете предотвратить UIAlertViewотклонение (нет shouldDismissфункции делегата AFAIK), поэтому я полагаю, если пользовательский ввод недействителен, вам нужно выставить новое предупреждение (или просто повторноshow это) до тех пор, пока правильный ввод не будет поступил.

Радоваться, веселиться!


1
С автоматическим подсчетом ссылок вы больше не должны сохранять и освобождать объекты самостоятельно.
Waqleh

5
Я знаю, но этот ответ был написан в 2011 году.
Warkst

3
Метод обесценился, начиная с версии iOS 9.0. Используйте вместо UIAlertController:
EckhardN

Если вам нужна поддержка по Swift 4: stackoverflow.com/a/10689318/525576
John Riselvato

186

Чтобы убедиться, что вы получаете обратные вызовы после того, как пользователь вводит текст, установите делегата внутри обработчика конфигурации. textField.delegate = self

Swift 3 и 4 (iOS 10-11):

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.default, handler: nil))
alert.addTextField(configurationHandler: {(textField: UITextField!) in
    textField.placeholder = "Enter text:"
    textField.isSecureTextEntry = true // for password input
})
self.present(alert, animated: true, completion: nil)

В Swift (iOS 8-10):

введите описание изображения здесь

override func viewDidAppear(animated: Bool) {
    var alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
    alert.addTextFieldWithConfigurationHandler({(textField: UITextField!) in
        textField.placeholder = "Enter text:"
        textField.secureTextEntry = true
        })
    self.presentViewController(alert, animated: true, completion: nil)
}

В Objective-C (iOS 8):

- (void) viewDidLoad 
{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"Click" style:UIAlertActionStyleDefault handler:nil]];
    [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
        textField.placeholder = @"Enter text:";
        textField.secureTextEntry = YES;
    }];
    [self presentViewController:alert animated:YES completion:nil];
}

ДЛЯ iOS 5-7:

UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"INPUT BELOW" delegate:self cancelButtonTitle:@"Hide" otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];

введите описание изображения здесь


ПРИМЕЧАНИЕ: Ниже не работает с iOS 7 (iOS 4-6 работает)

Просто чтобы добавить другую версию.

UIAlert с UITextField

- (void)viewDidLoad{

    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Preset Saving..." message:@"Describe the Preset\n\n\n" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
    UITextField *textField = [[UITextField alloc] init];
    [textField setBackgroundColor:[UIColor whiteColor]];
    textField.delegate = self;
    textField.borderStyle = UITextBorderStyleLine;
    textField.frame = CGRectMake(15, 75, 255, 30);
    textField.placeholder = @"Preset Name";
    textField.keyboardAppearance = UIKeyboardAppearanceAlert;
    [textField becomeFirstResponder];
    [alert addSubview:textField];

}

тогда я звоню, [alert show];когда хочу.

Метод, который идет вместе

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {         
    NSString* detailString = textField.text;
    NSLog(@"String is: %@", detailString); //Put it on the debugger
    if ([textField.text length] <= 0 || buttonIndex == 0){ 
        return; //If cancel or 0 length string the string doesn't matter
    }
    if (buttonIndex == 1) {
        ...

    }
}


1
У меня было что-то подобное со времен IOS 4, но, похоже, это не работает в OS 7. Теперь используйте код Wakrst - сохраните много строк кода.
Дэйв Эпплтон

Итак, что было бы правильным способом сделать это для iOS7? Мы работаем с iOS6 SDK, но на iOS7 он все еще выглядит странно.
sebrock

Добавлена ​​поддержка iOS7 в вопрос
Джон Риселвато

1
Обнаружено, что мне пришлось поместить в свой alertView:(UIAlertView *) clickedButtonAtIndex:(NSInteger)buttonIndexметод делегата следующее, чтобы получить значение textField.text: `NSString * theMessage = [alertView textFieldAtIndex: 0] .text;`
Джеймс Перих

1
замените «var alert» на «let alert» в быстром коде, чтобы соответствовать последней версии swift
Matei Suica

11

Протестировал третий фрагмент кода Warkst - отлично работал, за исключением того, что я изменил его на тип ввода по умолчанию вместо числового:

UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Hello!" message:@"Please enter your name:" delegate:self cancelButtonTitle:@"Continue" otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField * alertTextField = [alert textFieldAtIndex:0];
alertTextField.keyboardType = UIKeyboardTypeDefault;
alertTextField.placeholder = @"Enter your name";
[alert show];

Хорошая точка зрения! В то время я возился с textField и забыл изменить тип клавиатуры перед загрузкой фрагмента кода. Рад, что мой код может вам помочь!
Warkst

11

Начиная с IOS 9.0 используйте UIAlertController:

UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert"
                                                           message:@"This is an alert."
                                                          preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                  handler:^(UIAlertAction * action) {
                    //use alert.textFields[0].text
                                                       }];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction * action) {
                                                          //cancel action
                                                      }];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
    // A block for configuring the text field prior to displaying the alert
}];
[alert addAction:defaultAction];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];

5

Просто хотел добавить важную информацию, которая, как я полагаю, была упущена, возможно, с предположением, что те, кто ищет ответы, возможно, уже знают. Эта проблема возникает часто, и я тоже обнаружил, что застрял, когда попытался реализовать viewAlertметод для кнопок UIAlertViewсообщения. Для этого вам нужно сначала добавить класс делегата, который может выглядеть примерно так:

@interface YourViewController : UIViewController <UIAlertViewDelegate>

Также вы можете найти очень полезный учебник здесь !

Надеюсь это поможет.


5

Попробуйте этот код Swift в UIViewController -

func doAlertControllerDemo() {

    var inputTextField: UITextField?;

    let passwordPrompt = UIAlertController(title: "Enter Password", message: "You have selected to enter your passwod.", preferredStyle: UIAlertControllerStyle.Alert);

    passwordPrompt.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { (action) -> Void in
        // Now do whatever you want with inputTextField (remember to unwrap the optional)

        let entryStr : String = (inputTextField?.text)! ;

        print("BOOM! I received '\(entryStr)'");

        self.doAlertViewDemo(); //do again!
    }));


    passwordPrompt.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Default, handler: { (action) -> Void in
        print("done");
    }));


    passwordPrompt.addTextFieldWithConfigurationHandler({(textField: UITextField!) in
        textField.placeholder = "Password"
        textField.secureTextEntry = false       /* true here for pswd entry */
        inputTextField = textField
    });


    self.presentViewController(passwordPrompt, animated: true, completion: nil);


    return;
}

3

Swift 3:

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.default, handler: nil))
alert.addTextField(configurationHandler: {(textField: UITextField!) in
     textField.placeholder = "Enter text:"
})

self.present(alert, animated: true, completion: nil)

2

Я бы использовал a UIAlertViewс UITextFieldsubview. Вы можете добавить текстовое поле вручную или в iOS 5 использовать один из новых методов.


Я добавил следующий код из другого сообщения, но всплывающее окно появляется за пределами экрана (очень много сверху, видна только нижняя половина)
user605957

2
codeUIAlertView * myAlertView = [[UIAlertView alloc] initWithTitle: @ Сообщение «Ваш заголовок здесь»: @ «это покрывается» делегат: self cancelButtonTitle: @ «Отменить» otherButtonTitles: @ «ОК», ноль]; UITextField * myTextField = [[UITextField alloc] initWithFrame: CGRectMake (12.0, 45.0, 260.0, 25.0)]; CGAffineTransform myTransform = CGAffineTransformMakeTranslation (0,0, 130,0); [myAlertView setTransform: myTransform]; [myTextField setBackgroundColor: [UIColor whiteColor]]; [myAlertView addSubview: myTextField]; [myAlertView show]; [выпуск myAlertView];
user605957

Я пробовал аналогичный код, и он отображает представление предупреждения с текстовым полем и кнопками, но для текстового поля недостаточно места, он застревает между заголовком и кнопками и касается их обоих. Я попробовал несколько преобразований для масштабирования кадра, но кнопки остаются на своих местах, поэтому их тоже нужно переместить. Я не знаю, как перемещать кнопки, и не могу поверить, что все это необходимо для извлечения единственной строки текста из приглашения пользователю. Нет лучшего способа, чем этот?
Дин Дэвидс

2

Добавьте представления в UIAlertView следующим образом . В iOS 5 есть несколько "волшебных" вещей, которые делают это за вас (но это все по NDA).


Я пробовал это, и это немного работает. За исключением того, что всплывающее окно находится за пределами экрана (верхняя половина всплывающего окна отрублена). Есть идеи, почему?
user605957

У меня была такая же проблема, удаление setTranformMakeTranslation (0,109) исправило ее для меня как на ipad, так и на iphone. Без него он оказался в нужном месте.
joeld

2

В Xamarin и C #:

var alert = new UIAlertView ("Your title", "Your description", null, "Cancel", new [] {"OK"});
alert.AlertViewStyle = UIAlertViewStyle.PlainTextInput;
alert.Clicked += (s, b) => {
    var title = alert.ButtonTitle(b.ButtonIndex);
    if (title == "OK") {
        var text = alert.GetTextField(0).Text;
        ...
    }
};

alert.Show();

0

Основываясь на ответе Джона Риселвато, чтобы получить строку обратно из UIAlertView ...

alert.addAction(UIAlertAction(title: "Submit", style: UIAlertAction.Style.default) { (action : UIAlertAction) in
            guard let message = alert.textFields?.first?.text else {
                return
            }
            // Text Field Response Handling Here
        })

-1
UIAlertview *alt = [[UIAlertView alloc]initWithTitle:@"\n\n\n" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];

UILabel *lbl1 = [[UILabel alloc]initWithFrame:CGRectMake(25,17, 100, 30)];
lbl1.text=@"User Name";

UILabel *lbl2 = [[UILabel alloc]initWithFrame:CGRectMake(25, 60, 80, 30)];
lbl2.text = @"Password";

UITextField *username=[[UITextField alloc]initWithFrame:CGRectMake(130, 17, 130, 30)];
UITextField *password=[[UITextField alloc]initWithFrame:CGRectMake(130, 60, 130, 30)];

lbl1.textColor = [UIColor whiteColor];
lbl2.textColor = [UIColor whiteColor];

[lbl1 setBackgroundColor:[UIColor clearColor]];
[lbl2 setBackgroundColor:[UIColor clearColor]];

username.borderStyle = UITextBorderStyleRoundedRect;
password.borderStyle = UITextBorderStyleRoundedRect;

[alt addSubview:lbl1];
[alt addSubview:lbl2];
[alt addSubview:username];
[alt addSubview:password];

[alt show];
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.