UIView returns to its initial frame after UITextField subview becomeFirstResponder

152 views Asked by At

I have a UIView subclass that contains a UITextField as subview. The idea is to animate this UIView and make the UITexField becomeFirstResponder when animation has ended. For some reason, after animation completion block has been executed and the UITextField has becomeFirstResponder, the UIView returns to its initial frame.

Here is the dummy sample code:

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIView *redView;

@property (strong, nonatomic) UITextField *textField;

@property (strong, nonatomic) UITapGestureRecognizer *gesture;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.textField                 = [[UITextField alloc] initWithFrame:CGRectMake(0.f, 0.f, self.redView.frame.size.width, 30.f)];
    self.textField.backgroundColor = [UIColor lightGrayColor];

    [self.redView addSubview:self.textField];

    self.gesture = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                           action:@selector(animateRedView:)];

    [self.view addGestureRecognizer:self.gesture];
}

- (IBAction)animateRedView:(id)sender
{
    [UIView animateWithDuration:.5
                          delay:0
         usingSpringWithDamping:1.2
          initialSpringVelocity:5
                        options:0
                     animations:^{

                         CGRect redViewFrame = self.redView.frame;

                         [self.redView setFrame:CGRectMake((self.view.frame.size.width - redViewFrame.size.width),
                                                           redViewFrame.origin.y,
                                                           redViewFrame.size.width,
                                                           redViewFrame.size.height)];

                     } completion:^(BOOL finished) {

                         [self.textField becomeFirstResponder];

                     }];
}

@end

Any idea?

1

There are 1 answers

1
z2k On

Did you create redView in interface builder? If so it's going to have layout constraints attached to it.

You can remove them at runtime. Try adding this before you call setFrame

[self.redView removeConstraints:self.redView.constraints];

Also, you might try calculating the destination frame before the animation block (since you're calculating redFrame's new frame based on its current frame).

- (IBAction)animateRedView:(id)sender
{
    CGRect redViewFrame = self.redView.frame;
    CGRect newFrame = CGRectMake((self.view.frame.size.width - redViewFrame.size.width),
                                 redViewFrame.origin.y,
                                 redViewFrame.size.width,
                                 redViewFrame.size.height);
    [UIView animateWithDuration:.5
                          delay:0
         usingSpringWithDamping:1.2
          initialSpringVelocity:5
                        options:0
                     animations:^{
                         [self.redView setFrame:newFrame];
                     } completion:^(BOOL finished) {
                         [self.textField becomeFirstResponder];
                     }];
}