Keyboard from UIAlertController dismisses with delay - ios

I'm trying to make a login dialog in UIAlertController.
Here is my code:
+ (void)authorizationDialogShow
{
__block UITextField *loginTextField;
__block UITextField *passwordTextField;
UIAlertController *authorizationAlert = [UIAlertController alertControllerWithTitle:#"Authorization"
message:#"Enter login and password."
preferredStyle:UIAlertControllerStyleAlert];
[authorizationAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
loginTextField = textField;
loginTextField.placeholder = #"Login";
}];
[authorizationAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
passwordTextField = textField;
passwordTextField.placeholder = #"Password";
passwordTextField.secureTextEntry = YES;
}];
[authorizationAlert addAction:[UIAlertAction actionWithTitle:#"Login"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
NSString *login = loginTextField.text;
NSString *password = passwordTextField.text;
[GitAuthorization startAuthorizationWithLogin:login password:password];
}]];
[authorizationAlert addAction:[UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
NSLog(#"End editing");
[authorizationAlert.view endEditing:YES];
[loginTextField resignFirstResponder];
[passwordTextField resignFirstResponder];
}]];
[authorizationAlert show];
}
The problem is in cancel UIAlertAction. When I pressed this action, the keyboard dismissed with some delay. Not at the same time as UIAlertController. What's the problem?
I'm using pod FFGlobalAlertController. Here some example of this.

I have the same issue using UIAlertController.
My solution is to add a category on UIAlertController and call [self.view endEditing:YES] on viewWillDisappear. Import the category in prefix.pch if it's used widely.
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self.view endEditing:YES];
}
Thank for the answer from micap. See link below for detail:
iOS 8 Keyboard Dismissed delay after modal view controller is dismissed

Related

How allow copy/paste/cut in UIAlertView? (iOS, Objective C)

I want to allow users to copy/cut but mainly PASTE data from other apps into my app. I need to allow them to paste data in UIAlertView, when they are logging to the app. How can i make it?
This is my code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:[NSString stringWithFormat:NSLocalizedString(#"enter_login", nil)]
delegate:self
cancelButtonTitle:#"Ok"
[alert setAlertViewStyle:UIAlertViewStyleLoginAndPasswordInput];
[[alert textFieldAtIndex:0] setKeyboardType:UIKeyboardTypeEmailAddress];
[[alert textFieldAtIndex:1] becomeFirstResponder];
[UserDefaultsServices resetLoginCredentials];
[UserDefaultsServices resetLoginData];
self.alertView = alert;
[alert show];
It does this:
show what my code does, I need to allow users to paste data in password TextField
You can use this answer for swift versions :
Objective C version of shared answer is :
- (IBAction)showAlert:(id)sender {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Add New Name" message:#"Your message" preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = #"Name";
}];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = #"Password";
textField.secureTextEntry = true;
}];
UIAlertAction *saveAction = [UIAlertAction actionWithTitle:#"Save" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
// here you can access your textfields' texts
NSString *textField1 = alertController.textFields[0].text;
NSString *textField2 = alertController.textFields[1].text;
NSLog(#"Saving %# %#", textField1, textField2);
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
// here you can access your textfields' texts
NSString *textField1 = alertController.textFields[0].text;
NSString *textField2 = alertController.textFields[1].text;
NSLog(#"Canceled %# %#", textField1, textField2);
}];
[alertController addAction:saveAction];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
Above code work like this :

How to show time in UIAlertView?

In my app I'm implementing audio recorder. Everything working fine.
But when user taps on record button I have to show UIAlertView with time in seconds.
So that user can easily understand like recording.
I don't have any idea about this.
How can I do this or suggest me any other idea please.
UIAlertView is deprecated in iOS 8, now you can use UIAlertController with a preferredStyle of alert.
If the seconds are statics you can use
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#“Your title string”
message:[NSString stringWithFormat:#“Seconds: %f”,yourSecondsVariable];
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"OK",nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
I think that you can use timeIntervalSinceDate: (of NSDate) to initialize your yourSecondsVariable.
If you want the time to be dynamic (continually updating) then this should get you started.
#interface ViewController ()
#property (nonatomic, strong) UILabel *timeLabel;
#end
Implementation:
- (void)timer {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Time" message:#"\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
self.timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 260, 50)];
self.timeLabel.textAlignment = NSTextAlignmentCenter;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
self.timeLabel.text = [NSDate date].description;
}];
[alert.view addSubview:self.timeLabel];
[alert addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[timer invalidate];
}]];
[self presentViewController:alert animated:YES completion:nil];
}

Set limit to UITextField in ObjectiveC

I am creating login screen using Objective C in which i want to implement validation for User name(E-Mail) and password.How to implement this in very simple way.
You can always make use textField shouldChangeCharactersInRange delegate to handle the number of characters allowed in textField. Have look at the solution provided below :) Hope it helps
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if(textField == self.emailTextField){
if (textField.text.length < 30 || string.length == 0){
return YES;
}
else{
return NO;
}
}
}
EDIT
As per your comments you are not recieveing the textField delegates, so here is what you can do :)
In your ViewController, confirm the UITextFieldDelegate using,
YourViewController : UIViewController <UITextFieldDelegate>
In your viewDidLoad or ViewWillAppear set the textField delegate as self.
self.emailTextField.delegate = self;
If you click the Validate Button, set the validate button Action and see the below code,first check the two textfield empty or not, if you give text then again check its valid email type or not, then all conditions are true, then put your code and run,
-(IBAction)action:(id)sender
{
if (tfMail.text.length == 0 || tfPass.text.length == 0)
{
[self validatetextfield];
}
else if (![tfMail.text isEqualToString:#""])
{
NSString *emailRegEx = #"[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", emailRegEx];
//Valid email address
if ([emailTest evaluateWithObject:tfMail.text] == YES)
{
//Its validated put your success code,
}
else
{
UIAlertController *aler = [UIAlertController alertControllerWithTitle:#"Test!" message:#"Please Enter Valid Email Address. \nex. fdsjfkd#mail.com" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[aler addAction:action];
[self presentViewController:aler animated:YES completion:nil];
//not valid email address
}
}
}
Alert Message Method:
-(void) validatetextfield
{
if (tfMail.text.length==0) {
UIAlertController *aler = [UIAlertController alertControllerWithTitle:#"Email Field Empty!" message:#"Please Enter the Email" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[aler addAction:action];
[self presentViewController:aler animated:YES completion:nil];
[tfMail becomeFirstResponder];
}
else if (tfPass.text.length==0)
{
UIAlertController *aler = [UIAlertController alertControllerWithTitle:#"Password Field Empty!" message:#"Please Enter the Password" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[aler addAction:action];
[self presentViewController:aler animated:YES completion:nil];
[tfPass becomeFirstResponder];
}
}
its successfully working for me, hope its helpful.

How do i use the text in TextField in a block inside UIAlertController?

I have a UIAlertController, which contains a textfield and 2 buttons: OK and Cancel. i want to retrieve the text that the user entered in the textfield when he presses OK, but because the textfield is in a block i cant access the textField.text field that is inside the block from the OK button block. how do i access it and use the text entered by the user? see my code below.
- (IBAction)saveItinerary:(id)sender
{
NSString *itineraryNameInput = [[NSString alloc] init];
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Save Itinerary"
message:#"Enter Name for the Itinerary"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
{
}];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:ok];
[alert addAction:cancel];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = #"Name";
textField.text = itineraryNameInput;
}];
NSLog(#"name = %#", itineraryNameInput);
[self presentViewController:alert animated:YES completion:nil];
}
Use the textFields property of the UIAlertController.
UITextField *textField = alert.textFields.firstObject;

UIAlertController Does Not Return User Input

I'm using UIAlertController for the first time. I need to prompt the user for an input. Anyway, the following is what I have.
- (void)showAlert {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Hello!" message:#"Type something.") preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *noButton = [UIAlertAction actionWithTitle:#"Cancel") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}];
UIAlertAction *yesButton = [UIAlertAction actionWithTitle:#"Enter") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
//NSString *input = alert.textFields[0].text;
//NSLog(#"input was '%#'", input);
UITextField *textField = alert.textFields[0];
NSLog(#"%#",textField.text); // <====== It's not returned
}];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
[textField addTarget:self action:#selector(alertTextFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
[yesButton setEnabled:NO];
}];
[alert addAction:noButton];
[alert addAction:yesButton];
[self presentViewController:alert animated:YES completion:nil];
}
- (void)alertTextFieldDidChange:(UITextField *)sender {
UIAlertController *alertController = (UIAlertController *)self.presentedViewController;
if (alertController) {
UITextField *textfield = alertController.textFields.firstObject;
UIAlertAction *okAction = alertController.actions.lastObject;
okAction.enabled = [self validateName2:textfield.text:5]; // function for validating user input
}
}
For some reason, when the user tap Yes, the application doesn't return user input. In fact, Xcode dashes 'text' as in 'NSString *input = alert.textFields[0].text. A strange thing is that UIAlertView doesn't return user input. That's why I've switched to UIAlertController.
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if ([alertView tag] == 101) {
if (buttonIndex == 1) {
NSString *username = [[alertView textFieldAtIndex:0] text];
NSLog(#"%#",username); // <====== It's never returned.
}
}
}
Anyway, I wonder what I'm doing wrong with UIAlertController?
Muchos thankos
p.s. I'm using Xcode 6.4 (6E35b). This issue may be caused by Xcode. If I debug the code with the iPad2 simulator, it'll actually return user input while it doesn't if I use the iPhone4S simulator.
Use this for textField in alertcontroller
__block typeof(self) weakSelf = self;
UIAlertController *alertController;
alertController = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField)
{
textField.tag = 1001;
textField.delegate = weakSelf;
textField.placeholder = #"";
[textField addTarget:weakSelf action:#selector(alertTextFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
}];
//OK Button
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
UITextField *textField = alertController.textFields.firstObject;
// Do stuff here
}];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
- (void)alertTextFieldDidChange:(UITextField *)sender
{
alertController = (UIAlertController *)self.presentedViewController;
if (alertController)
{
UITextField *textField = alertController.textFields.firstObject;
UIAlertAction *okAction = alertController.actions.lastObject;
okAction.enabled = textField.text.length > 0; // condition to enable button
}
}
#pragma mark - UITextField delegate methods
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
I would recommend using UITextFieldDelegate to handle the textField!
Set textField.delegate = self and then use the - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string method to do what you do in alertTextFieldDidChange if the replacementString has a length of > 0.
You are provided with delegate methods for UITextField so you don't have to create the selectors yourself, I recommend you use them to their fullest!
Here are the docs in case you want to know more! https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextFieldDelegate_Protocol/

Resources