Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextField textColor reverts after resignFirstResponder

I have a UIButton that controls the textColor of a UITextField, and I have found that when I call resignFirstResponder on the UITextField, any changes to the textColor made while the text field was first responder are lost, and the color is reverted to the state before becomeFirstResponder. The behavior I am looking for is that the textColor should remain as whatever is chosen while the text field is first responder.

Here is the relevant code:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tf = [[UITextField alloc] initWithFrame:CGRectMake(0.0f, 120.0f, self.view.bounds.size.width, 70.0f)];
    self.tf.delegate = self;
    self.tf.text = @"black";
    self.tf.font = [UIFont fontWithName:@"AvenirNext-DemiBold" size:48.0f];
    self.tf.textColor = [UIColor blackColor];
    [self.view addSubview:self.tf];
    self.tf.textAlignment = UITextAlignmentCenter;

    UIButton *b = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 220.0f, self.view.bounds.size.width, 20.0f)];
    [b addTarget:self action:@selector(changeColor:) forControlEvents:UIControlEventTouchUpInside];
    [b setTitle:@"Change color" forState:UIControlStateNormal];
    [b setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
    [self.view addSubview:b];
}

- (void)changeColor:(UIButton *)button {
    if ([self.tf.textColor isEqual:[UIColor blackColor]]) {
        self.tf.text = @"red";
        self.tf.textColor = [UIColor redColor];
    } else {
        self.tf.text = @"black";
        self.tf.textColor = [UIColor blackColor];
    }
}

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

More specifically, the behavior is produced by the following actions:

  1. UITextField *tf initially black.
  2. Tap tf to becomeFirstResponder.
  3. Tap UIButton *b, tf.textColor changes to red (text also changes to @"red", although this is not necessary).
  4. Tap keyboard Return to resignFirstResponder, tf.textColor reverts back to black (text stays as @"red").

Analogously, if the initial textColor is red, the textField reverts back to red.

I've created an example project with only the features necessary to produce this behavior (available here). Thanks in advance.

like image 627
cbosborn Avatar asked Mar 09 '14 17:03

cbosborn


1 Answers

As a workaround, you can just store the selected color on a property when the button is pressed and do this:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    textField.textColor = self.selectedColor;
    return YES;
}

UPDATE

As noted in the comments, a better place to put this workaround seems to be in textFieldDidEndEditing because it handles the case of jumping between fields:

- (void)textFieldDidEndEditing:(UITextField *)textField {
    textField.textColor = self.selectedColor;
}
like image 103
Timothy Moose Avatar answered Nov 11 '22 02:11

Timothy Moose