在TextField焦点更改后,动画UIView会更改帧位置

时间:2015-01-22 22:00:43

标签: ios objective-c autolayout custom-controls uiviewanimation

重构我的代码值得发布并获得反馈后的一个奇怪问题,让我整天都疯狂。

我有一个可重复使用的自定义控件,它的XIB包含一个带有子视图3 UITextField(UserName,Password,Email)的UIView,想象它是一个注册输入框。我遵守UITextFieldDelegate以在键盘上操作Next,返回键盘按钮。

在我的所有观看中,我都非常谨慎地使用AutoLayout约束。

我在文件的所有者UIView后代自定义类(SignUpInputView.m)中初始化我的nib。

- (void) setupView
    {
    self.view = [self loadViewFromNib];
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.bounds = self.view.bounds;
    _intrinsicContentSize = self.bounds.size;
    [self setTranslatesAutoresizingMaskIntoConstraints:NO];
    self.view.layer.borderWidth = 1.0f;
    self.view.layer.borderColor = [self greyColor];
    [self setupOutlets]; // I set the UITextFields delegate
    [self addSubview:self.view];
    }

// Override the intrinsicContectSize method

- (CGSize)intrinsicContentSize
    {
    return _intrinsicContentSize;
    }

在从BaseViewController派生的LoginViewController中,我使用自定义控件并使用属性设置getter方法。

@property (strong, nonatomic, getter=getSignUpInputView) SignUpInputView* signUpInputView;

- (SignUpInputView*) getSignUpInputView
    {
    if (!_signUpInputView)
        {
        _signUpInputView = [SSESignUpInputView new];
        _signUpInputView.hidden = YES;
        _signUpInputView.alpha = 0.0f;
        [self.view addSubview:_signUpInputView];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_signUpInputView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0.0f]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_signUpInputView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0f constant:0.0f]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_signUpInputView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f]];
        [_signUpInputView addConstraint:[NSLayoutConstraint constraintWithItem:_signUpInputView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_signUpInputView attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f]];
        }
    return _signUpInputView;
    }

我根据用户采取的操作(按下注册按钮,取消按钮)在SignUpViewController中处理隐藏和alpha属性。

在SignUpViewController中,当用户按下SignUp按钮时,我有一个方法。

- (IBAction)signupButtonTouchUpInside:(UIButton*)sender
    {
    // Call a method that sets some animations

    // Set some other animations here.
    [self.view layoutIfNeeded];
    [UIView transitionWithView:self.uploadPhotoButton duration:1.0f options:UIViewAnimationOptionTransitionFlipFromRight animations:
        ^{
        self.aView.alpha = 1.0f;
        self.anotherView.alpha = 0.0f;
        [self.view layoutIfNeeded];
        }
    completion:nil];

    SignUpInputView* signUpView = self.signUpInputView;
    signUpView.hidden = NO;
    [signUpView fullNameBecomeFirstResponder];
    // This is a method from the BaseViewController
    [super animateViewFromLeftOffsetOnTopOfKeyboard:signUpView];
    }

BaseViewController animateViewFromLeftOffsetOnTopOfKeyboard:implementation。

- (void) animateViewFromLeftOffsetOnTopOfKeyboard:(UIView*)view
    {
    // Execute with some delay to make sure I have the keyboard's height from the UIKeyboardDidChangeFrameNotification
    [self executeBlock:
        ^{
        CGFloat yInputView = self.view.bounds.size.height - [self keyboardHeight] - view.bounds.size.height/2;
        view.center = CGPointMake(-view.bounds.size.width, yInputView);
        view.alpha = 1.0f;
        [self.view layoutIfNeeded];
        [UIView animateWithDuration:1.0f delay:0.0f usingSpringWithDamping:0.8f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveEaseOut animations:
            ^{
            view.center = CGPointMake(view.bounds.size.width/2, yInputView);
            [self.view layoutIfNeeded];
            }
        completion:nil];
        }
    withDelay:0.7];
    }

一切都很好用,但现在我有这样的错误,就好像view.center = CGPointMake(view.bounds.size.width/2, yInputView); [UIView animateWithDuration:]方法的animateViewFromLeftOffsetOnTopOfKeyboard:代码块中没有signupButtonTouchUpInside:一样。

问题是,您点击了初始UITextField以外的文本字段(全名,请参阅上面{{1}}方法中的代码),SignUpInputView会立即移到屏幕顶部。

我想念一些东西,但事情是它在从BaseController重构NSLayoutConstraints到getter属性方法之前工作,因为两次添加约束的崩溃,以及其他一般隐藏的alpha属性操作。

1 个答案:

答案 0 :(得分:1)

在这种情况下,您根本不应该设置任何帧。添加子视图,并为其设置约束以设置其初始位置;为要修改的任何约束创建属性。要为视图设置动画,请将这些约束的常量值更改为您想要的值,然后在动画块中调用layoutIFNeeded。