在textFieldDidBeginEditing方法中更新约束会导致文本反弹

时间:2015-03-20 06:52:49

标签: ios uitextfield autolayout

我有一个UIView,其中包含另一个名为UIView的{​​{1}}对象。在contentView内,我有几个contentView个对象。因此,当前编辑UITextField始终可见且未被键盘隐藏,我正在改变UITextField方法内contentView的约束。这意味着contentView在父textFieldDidBeginEditing:内向上和向下滑动,并保持相关的UIView可见。这部分工作正常,但这是一个代码片段:

UITextField

我注意到,如果我在第一个- (void)textFieldDidBeginEditing:(UITextField *)textField //offset calculation removed for clarity NSInteger offset = .... self.contentViewTopConstraint.constant = -offset; self.contentViewBottomConstraint.constant = offset; [self.view setNeedsUpdateConstraints]; [UIView animateWithDuration:0.3 animations:^{ [self.view layoutIfNeeded]; }]; } 中输入一些文字,然后点击第二个UITextField,则第一个UITextField中的文字会向上跳跃然后再次向下。如果我在上面的代码片段中禁用动画,这种行为就会消失。所以我的猜测是,当编辑UITextField时,会设置一些其他约束,然后随着焦点远离UITextField而改变。当我告诉视图以动画方式更新它的约束时,这会导致文本移动。

有什么方法可以避免这种情况,但仍然保持动画来上下移动contentView?

修改:在更新任何约束之前添加额外的UITextField调用可解决此问题。我仍然不确定可能会发生什么,或者真的为什么要修复它。有人有任何见解吗?

2 个答案:

答案 0 :(得分:2)

我已经了解到约束动画的正确方法是这样的:

- (void)textFieldDidBeginEditing:(UITextField *)textField
    //offset calculation removed for clarity
    NSInteger offset = ....

    [self.view layoutIfNeeded];
    self.contentViewTopConstraint.constant = -offset;
    self.contentViewBottomConstraint.constant = offset;

    [UIView animateWithDuration:0.3 animations:^{
        [self.view layoutIfNeeded];
    }];
}

这解决了我遇到的问题。

答案 1 :(得分:0)

我不确定你的代码有什么问题,我需要更多的代码来告诉我这里有什么问题,但你可以使用这段代码,它会对你有用

-(void)addObservers
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardIsShowing:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardIsHiding:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}

-(void)removeObservers
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (void)keyboardIsShowing:(NSNotification*)notification
{

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
    [UIView setAnimationBeginsFromCurrentState:YES];

    int scaleFactor = 0;
    if([oldPasswrdField isFirstResponder])
        scaleFactor = 20;
    else if([newPasswrdField isFirstResponder])
        scaleFactor = 76;
    else if([confirmPasswrdField isFirstResponder])
        scaleFactor = 132;

    self.contentView.frame = CGRectMake(self.contentView.frame.origin.x, self.view.frame.origin.y-scaleFactor,self.contentView.frame.size.width, self.contentView.frame.size.height);


    [UIView commitAnimations];

}

- (void)keyboardIsHiding:(NSNotification*)notification
{

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
    [UIView setAnimationBeginsFromCurrentState:YES];


    self.contentView.frame = CGRectMake(self.contentView.frame.origin.x, 0, self.contentView.frame.size.width, self.contentView.frame.size.height);

    //self.view.frame = frame;


    [UIView commitAnimations];

}

您在scalefactor方法中看到了keyboardIsShowing。需要根据您正在编辑的文本字段进行设置。如果可以,您只需获取当前响应的文本字段并取其origin.y并根据该字段设置比例因子。另外,在addObservers中致电viewDidAppear,然后在removeObservers中致电viewDidDisappear。或者根据您的需要,但不要忘记给他们打电话一次。

编辑:告诉我,如果这对你有用,或者如果你需要进一步的帮助,我很乐意提供帮助。