done button begins enabled and disables itself after start typing the username,skips the validation method

StackOverflow https://stackoverflow.com/questions/18653327

سؤال

I have been trying done perform a segue after validation, but as soon as i set the segue from storyboard, the compiler just ignores both the validation and the -(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender method and enables the done button from the start.I tried this,this,this but I believe I missed a key point. Before connecting the segue, i was able to validate my sign up and it worked just fine(meaning done button gets enabled only after the going through the validation method and I am able to register user to parse). I believe i am using the right method(shouldperformsegue method) but wrong parameters. So if someone can help me understand what I am doing wrong, I would appreciate. Thank you.

SignUpViewController.h

#import <UIKit/UIKit.h>


@interface SignUpViewController : UIViewController<UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UIBarButtonItem *doneButton;
@property (weak, nonatomic) IBOutlet UITextField *userNameField;
@property (weak, nonatomic) IBOutlet UITextField *passwordField;
@property (weak, nonatomic) IBOutlet UITextField *reEnterPasswordField;
- (IBAction)done:(id)sender;
- (IBAction)cancel:(id)sender;

SignUpViewController.m

#import "SignUpViewController.h"
#import <Parse/Parse.h>
#import "ActivityView.h"
#import "ProfileViewController.h"

@interface SignUpViewController ()
- (void)textInputChanged:(NSNotification *)note;
-(void)processFieldEntries;
- (BOOL)shouldEnableDoneButton;
@end

@implementation SignUpViewController

@synthesize doneButton = _doneButton;
@synthesize userNameField = _userNameField;
@synthesize passwordField = _passwordField;
@synthesize reEnterPasswordField = _reEnterPasswordField;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

        [[NSNotificationCenter defaultCenter ]addObserver:self selector:@selector(textInputChanged:) name:  UITextFieldTextDidChangeNotification object:_userNameField];
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_passwordField];
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_reEnterPasswordField];

    _doneButton.enabled = YES;
    NSLog(@"nsnotification is working fine");

}
-(void)viewWillAppear:(BOOL)animated
{
    [_userNameField becomeFirstResponder];
    [super viewWillAppear:animated];
    NSLog(@"indeed usernamefield became a first responder");

}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if (textField == _userNameField ) {
        [_userNameField becomeFirstResponder];
    }
    if (textField == _passwordField) {
        [_passwordField becomeFirstResponder];
    }
    if (textField == _reEnterPasswordField)
    {
        [_reEnterPasswordField becomeFirstResponder];
    }
    NSLog(@"keyboard action works fine ");
    return YES;
}
-(BOOL)shouldEnableDoneButton
{
    BOOL enableDoneButton = NO;

    if (_userNameField.text != nil &&
        _userNameField.text.length > 0 &&
        _passwordField.text != nil &&
        _passwordField.text.length > 0 &&
        _reEnterPasswordField.text != nil &&
        _reEnterPasswordField.text.length > 0)
    {
        enableDoneButton = YES;
        NSLog(@"done button enabled");
    }
    return enableDoneButton;

}
-(void)textInputChanged:(NSNotification *)note
{
    _doneButton.enabled = [self shouldEnableDoneButton];

}
- (IBAction)done:(id)sender {
    [_userNameField resignFirstResponder];
    [_passwordField resignFirstResponder];
    [_passwordField resignFirstResponder];
    [self processFieldEntries];

}

- (IBAction)cancel:(id)sender
{
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];

}
-(void)processFieldEntries
{
    // Check that we have a non-zero username and passwords.
    // Compare password and passwordAgain for equality
    // Throw up a dialog that tells them what they did wrong if they did it wrong.

    NSString *username = _userNameField.text;
    NSString *password = _passwordField.text;
    NSString *passwordAgain = _reEnterPasswordField.text;
    NSString *errorText = @"Please ";
    NSString *usernameBlankText = @"enter a username";
    NSString *passwordBlankText = @"enter a password";
    NSString *joinText = @", and ";
    NSString *passwordMismatchText = @"enter the same password twice";

    BOOL textError = NO;
    NSLog(@"validation begins here");

    // Messaging nil will return 0, so these checks implicitly check for nil text.

    if (username.length == 0 || password.length == 0 || passwordAgain.length == 0) {
        textError = YES;
    }
    if (passwordAgain.length == 0) {
        [_reEnterPasswordField becomeFirstResponder];
    }
    if (username.length == 0) {
        [_userNameField becomeFirstResponder];
    }
    if (password.length == 0)
    {
        [_passwordField becomeFirstResponder];
    }
    if (username.length == 0) {
        errorText = [errorText stringByAppendingString:usernameBlankText];
    }
    if (password.length == 0 || passwordAgain.length == 0) {
        if (username.length == 0) {
            // We need some joining text in the error
            errorText = [errorText stringByAppendingString:joinText];
        }
        errorText = [errorText stringByAppendingString:passwordBlankText];
    }else if ([password compare:passwordAgain] != NSOrderedSame)
    {
        // We have non-zero strings.
        // Check for equal password strings.
        textError = YES;
        errorText = [errorText stringByAppendingString:passwordMismatchText];
        [_passwordField becomeFirstResponder];
    }
    if (textError) {
        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:errorText message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
        [alertView show];
        return;
    }
    NSLog(@"validation works just fine");

    // Everything looks good; try to log in.
    // Disable the done button for now.
    _doneButton.enabled = NO;
    ActivityView *activityCircle = [[ActivityView alloc] initWithFrame:CGRectMake(0.f, 0.f, self.view.frame.size.width, self.view.frame.size.height)];
    UILabel *label = activityCircle.label;
    label.text = @"Signing You Up";
    label.font = [UIFont boldSystemFontOfSize:20.f];
    [activityCircle.activityIndicator startAnimating];
    [activityCircle layoutSubviews];

    [self.view addSubview:activityCircle];
    NSLog(@"activity view works just fine");

    //parse registeration
    // Call into an object somewhere that has code for setting up a user.
    // The app delegate cares about this, but so do a lot of other objects.
    // For now, do this inline.

    PFUser *user = [PFUser user];
    user.username = username;
    user.password = password;
    [user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (error) {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[[error userInfo] objectForKey:@"error"] message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok", nil];
            [alertView show];
            _doneButton.enabled = [self shouldEnableDoneButton];
            [activityCircle.activityIndicator stopAnimating];
            [activityCircle removeFromSuperview];
            // Bring the keyboard back up, because they'll probably need to change something.
            [_userNameField becomeFirstResponder];
            return;
        }
        // Success!
        [activityCircle.activityIndicator stopAnimating];
        [activityCircle removeFromSuperview];
        //add the next screen here
    }];
    NSLog(@"user signedup just fine");
    //now pass the view from sign up to profile view
}
/*
 //this one didnt work
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{

    ProfileViewController *myProfileView = [segue destinationViewController];
    if (_doneButton.enabled == YES) {
           [myProfileView performSegueWithIdentifier:@"SignUpSegue" sender:_doneButton];
    }


}
 */
-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{   NSLog(@"is this method visible");
    if (_doneButton.enabled == YES) {
        [self performSegueWithIdentifier:@"SignUpSegue" sender:_doneButton];
    }

return NO;

}

 @end

the logs I see if I click the done button right away

2013-09-06 01:20:07.148 nsnotification is working fine 2013-09-06 01:20:07.155 indeed usernamefield became a first responder 2013-09-06 01:20:11.290 is this method visible

the logs I see if I go through the signup process 2013-09-06 01:22:20.117 nsnotification is working fine 2013-09-06 01:22:20.120 indeed usernamefield became a first responder 2013-09-06 01:22:27.701 done button enabled 2013-09-06 01:22:28.094 done button enabled 2013-09-06 01:22:30.196 is this method visible

هل كانت مفيدة؟

المحلول

Your done button validation is faulty. You are not checking if password repeat is the same as the first password.

Also, make sure that in storyboard the done button disabled by default. Only enable it explicitly.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top