Search code examples
iosobjective-cuialertcontrolleruitextfielddelegate

UIAlertController dismiss in fraction of second


I'm implementing UIAlertController as shown:

-(void)createAlert{

    UIAlertController * alert=   [UIAlertController
                                  alertControllerWithTitle:@"Ошибка электронного адреса"
                                  message:@"Ваш электронный адрес должен содержать символ @ и название домена"
                                  preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction* yesButton = [UIAlertAction
                                actionWithTitle:@"Сейчас исправлю"
                                style:UIAlertActionStyleDefault
                                handler:^(UIAlertAction * action)
                                {
                                    //Handel your yes please button action here
                                    [alert dismissViewControllerAnimated:YES completion:nil];

                                }];


    [alert addAction:yesButton];


    [self presentViewController:alert animated:YES completion:nil];
}

However, it only show alert for a fraction of second (about 0,5 sec). How could i fix that, so it will dismiss only after user press "yes" button?

UPDATE - there is full implementation code as required:

#define RGB(r, g, b) \
[UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define RGBA(r, g, b, a) \
[UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)]

//cell.textColor = RGB(0x66, 0x33, 0x33);

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UILabel *enterLoginLabel;
@property (weak, nonatomic) IBOutlet UILabel *enterEmailTextLabel;
@property (weak, nonatomic) IBOutlet UILabel *confirmEmailTextLabel;

@property (weak, nonatomic) IBOutlet UIButton *maleButton;
@property (weak, nonatomic) IBOutlet UIButton *femaleButton;

@property (weak, nonatomic) IBOutlet UITextField *loginTextField;
@property (weak, nonatomic) IBOutlet UITextField *emailTextField;
@property (weak, nonatomic) IBOutlet UITextField *emailConfirmTextField;




@end

@implementation ViewController {

    BOOL isMale;
    BOOL isFemale;
    BOOL isStartTyping;
    BOOL loginIsMoved;
    BOOL emailIsMoved;
    BOOL emailConfirmIsMoved;
    int currentIndex;


}

- (void)viewDidLoad {

    [super viewDidLoad];

    [self setColors];
    [self addTargets];

}


#pragma mark - gender check


- (IBAction)maleButtonTapped:(id)sender {

    if (!isMale && !isFemale){

        [UIView animateWithDuration:2.0 animations:^{
            self.maleButton.backgroundColor = RGB(0x63, 0xB8, 0xFF);
        } completion:NULL];

        isMale = YES;

    }

    if (isFemale && !isMale){

        [UIView animateWithDuration:2.0 animations:^{
            self.femaleButton.backgroundColor = RGB(0xC1, 0xCD, 0xCD);
        } completion:NULL];

        isFemale = NO;

        [UIView animateWithDuration:2.0 animations:^{
            self.maleButton.backgroundColor = RGB(0x63, 0xB8, 0xFF);
        } completion:NULL];

        isMale = YES;
    }

}

- (IBAction)femaleButtonTapped:(id)sender {


    if (!isMale && !isFemale){

        [UIView animateWithDuration:2.0 animations:^{
            self.femaleButton.backgroundColor = RGB(0xFF, 0x83, 0xFA);
        } completion:NULL];

        isFemale = YES;
    }

    if (isMale && !isFemale){

        [UIView animateWithDuration:2.0 animations:^{
            self.maleButton.backgroundColor = RGB(0xC1, 0xCD, 0xCD);
        } completion:NULL];

        isMale = NO;

        [UIView animateWithDuration:2.0 animations:^{
            self.femaleButton.backgroundColor = RGB(0xFF, 0x83, 0xFA);
        } completion:NULL];

        isFemale = YES;

    }

}


#pragma mark - color

-(void)setColors{

    self.view.backgroundColor = RGB(0xF0, 0xE6, 0x8c);
    self.maleButton.backgroundColor = RGB(0xC1, 0xCD, 0xCD);
    self.femaleButton.backgroundColor = RGB(0xC1, 0xCD, 0xCD);
}

#pragma mark - UITextFieldDelegate

-(void)textFieldDidBeginEditing:(UITextField *)textField
{



    if (textField == self.loginTextField){
        NSLog(@"login  text field");
        currentIndex = 1;
    }

    if (textField == self.emailTextField){
        NSLog(@"Email text field");
        currentIndex = 2;
    }

    if (textField == self.emailConfirmTextField){
        NSLog(@"Confirm email text field");
        currentIndex = 3;
    }

    NSLog(@"begin");
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{


    if ([textField.text length] >0){

        [self labelWithIndex:currentIndex].hidden = YES;
    }

    NSLog(@"End edit");
    [self dismissViewControllerAnimated:YES completion:nil];
}


-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{

    return YES;
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchesBegan:withEvent:");
    [self.view endEditing:YES];
    [super touchesBegan:touches withEvent:event];


}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{

    if (textField == self.emailTextField){

    if ([self NSStringIsValidEmail:textField.text]){

        [self animateWithTextField:textField];

    }   else {

        [self createAlert];
    }

    }


    return YES;
}

#pragma mark - animation and frame

-(CGRect)rectWithLabe:(UILabel*)label{

    CGRect newRect = label.frame;
    newRect.origin.y = newRect.origin.y - 25;
    newRect.size.width =  newRect.size.width + 100;

    return newRect;
}

-(void)addTargets{

    [self.loginTextField addTarget:self
                            action:@selector(textFieldDidChange:)
                  forControlEvents:UIControlEventEditingChanged];

    [self.emailTextField addTarget:self
                            action:@selector(textFieldDidChange:)
                  forControlEvents:UIControlEventEditingChanged];

    [self.emailConfirmTextField addTarget:self
                                   action:@selector(textFieldDidChange:)
                         forControlEvents:UIControlEventEditingChanged];

}

-(CGRect)finalRectForLabelWithTextField:(UITextField*)textField{

    CGRect frameRect = textField.frame;
    frameRect.origin.x = 50;
    return frameRect;
}



-(void) textFieldDidChange:(UITextField *)textField
{

    // Logic for login text field

    if([textField.text length]>0){

        if (currentIndex == 1 && !loginIsMoved){

            NSLog(@"Current index is 1");
            [self animateWithLabel:self.enterLoginLabel andRect:[self rectWithLabe:[self enterLoginLabel]]];
            loginIsMoved = YES;

        }



    } else {

        if (currentIndex == 1){
            // self.rect = self.labelPlaceHolder.frame;
            [self animateWithLabel:self.enterLoginLabel andRect:[self finalRectForLabelWithTextField:textField]];

        }

        loginIsMoved = NO;
    }

    // Logic for email text field

    if([textField.text length]>0){

        if (currentIndex == 2 && !emailIsMoved){

            NSLog(@"Current index is 1");
            [self animateWithLabel:self.enterEmailTextLabel andRect:[self rectWithLabe:[self enterEmailTextLabel]]];
            emailIsMoved = YES;

        }



    } else {

        if (currentIndex == 2){
            // self.rect = self.labelPlaceHolder.frame;
            [self animateWithLabel:self.enterEmailTextLabel andRect:[self finalRectForLabelWithTextField:textField]];

        }

        emailIsMoved = NO;
    }

    // Logic for confirm email text field

    if([textField.text length]>0){

        if (currentIndex == 3 && !emailConfirmIsMoved){

            NSLog(@"Current index is 1");
            [self animateWithLabel:self.confirmEmailTextLabel  andRect:[self rectWithLabe:[self confirmEmailTextLabel ]]];
            emailConfirmIsMoved = YES;

        }



    } else {

        if (currentIndex == 3){
            // self.rect = self.labelPlaceHolder.frame;
            [self animateWithLabel:self.confirmEmailTextLabel andRect:[self finalRectForLabelWithTextField:textField]];

        }

        emailConfirmIsMoved = NO;
    }
}


-(void)createCircle{

    UIView *circleView;

    circleView = [[UIView alloc] initWithFrame:CGRectMake(100,100,20,20)];
    circleView.alpha = 0.5;
    circleView.layer.cornerRadius = 10;
    circleView.backgroundColor = RGB(0x00, 0xC7, 0x8c);

    [self.view addSubview:circleView];
}

-(void)animateWithLabel:(UILabel*)label andRect:(CGRect)rect{

    [UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:0.3 options:0 animations:^{

        label.frame = rect;

    } completion:^(BOOL finished) {

    }];


}

-(void)animateWithTextField:(UITextField*)textField{

    UIView *circleView;

    circleView = [[UIView alloc] initWithFrame:CGRectMake(textField.frame.origin.x, textField.frame.origin.y, 20, 20)];
    circleView.alpha = 0.5;
    circleView.layer.cornerRadius = 10;
    circleView.backgroundColor = RGB(0x00, 0xC7, 0x8c);
    circleView.hidden = YES;

    [self.view addSubview:circleView];


    [UIView animateWithDuration:1.5 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:0.3 options:0 animations:^{

        circleView.hidden = NO;
        CGRect newRect = textField.frame;
        newRect.origin.y = newRect.origin.y - 25;
        newRect.size.width =  newRect.size.width + 100;

        circleView.frame = CGRectMake(newRect.origin.x, newRect.origin.y, 20, 20);
        [self labelWithIndex:2].hidden = YES;


    } completion:^(BOOL finished) {

    }];

}



#pragma mark - helper methods

-(void)createAlert{

    UIAlertController * alert=   [UIAlertController
                                  alertControllerWithTitle:@"Ошибка электронного адреса"
                                  message:@"Ваш электронный адрес должен содержать символ @ и название домена"
                                  preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction* yesButton = [UIAlertAction
                                actionWithTitle:@"Сейчас исправлю"
                                style:UIAlertActionStyleDefault
                                handler:^(UIAlertAction * action)
                                {
                                    //Handel your yes please button action here
                                    [alert dismissViewControllerAnimated:YES completion:nil];

                                }];


    [alert addAction:yesButton];


    [self presentViewController:alert animated:YES completion:nil];
}

-(UILabel*)labelWithIndex:(int)myIndex{

    UILabel *correctLabel;

    if (myIndex == 1){
        correctLabel = self.enterLoginLabel;
    }

    if (myIndex == 2){
        correctLabel = self.enterEmailTextLabel;
    }

    if (myIndex == 3){
        correctLabel = self.confirmEmailTextLabel;
    }

    return correctLabel;

}





-(BOOL) NSStringIsValidEmail:(NSString *)checkString
{
    BOOL stricterFilter = NO;
    NSString *stricterFilterString = @"^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$";
    NSString *laxString = @"^.+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*$";
    NSString *emailRegex = stricterFilter ? stricterFilterString : laxString;
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:checkString];
}

Solution

  • remove the line dismissViewControllerAnimated:YES in the textFieldDidEndEditing, and try again.

    textFieldDidEndEditing, will get called after the textfield text change is finished.

    From the documentation:

    Tells the delegate that editing stopped for the specified text field.

    So even though you present the alert in the text field delegate method, it get dismissed soon, as the other text field delegate method will get hit.