动画 UIView 在 TextField 焦点更改后更改框架位置
Animating UIView changes frame position after TextField focus change
重构我的代码后出现了一个奇怪的问题,值得发布并获得反馈,让我疯狂了一整天。
我有一个可重复使用的自定义控件,它的 XIB 包含一个带有子视图 3 UITextField(用户名、密码、电子邮件)的 UIView,假设它是一个注册输入框。我符合 UITextFieldDelegate 作用于键盘 接下来,Return 键盘按钮按下。
在我所有的观点中,我都非常谨慎地使用 AutoLayout 约束。
我在文件的所有者 UIView 后代自定义中初始化我的笔尖 class (SignUpInputView.m)。
- (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: 实现。
- (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];
}
一切正常,但现在我遇到了这个错误,好像它没有在 animateViewFromLeftOffsetOnTopOfKeyboard:
方法的 [UIView animateWithDuration:]
代码块中保留 view.center = CGPointMake(view.bounds.size.width/2, yInputView);
。
问题是,您点击初始 UITextField 以外的文本字段(全名,请参阅上面 signupButtonTouchUpInside:
方法中的代码)并且 SignUpInputView 立即移动到屏幕顶部。
我错过了一些东西,但事情是在将 NSLayoutConstraints 从 BaseController 重构到 getter 属性方法之前它正在工作,因为两次添加约束的崩溃,以及其他一般隐藏的 alpha 属性操作。
在这种情况下,您根本不应该设置任何框架。添加子视图,并为其设置约束以设置其初始位置;为您要修改的任何约束设置属性。要为视图设置动画,请将这些约束的常量值更改为您想要的值,然后在动画块中调用 layoutIFNeeded。
重构我的代码后出现了一个奇怪的问题,值得发布并获得反馈,让我疯狂了一整天。
我有一个可重复使用的自定义控件,它的 XIB 包含一个带有子视图 3 UITextField(用户名、密码、电子邮件)的 UIView,假设它是一个注册输入框。我符合 UITextFieldDelegate 作用于键盘 接下来,Return 键盘按钮按下。
在我所有的观点中,我都非常谨慎地使用 AutoLayout 约束。
我在文件的所有者 UIView 后代自定义中初始化我的笔尖 class (SignUpInputView.m)。
- (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: 实现。
- (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];
}
一切正常,但现在我遇到了这个错误,好像它没有在 animateViewFromLeftOffsetOnTopOfKeyboard:
方法的 [UIView animateWithDuration:]
代码块中保留 view.center = CGPointMake(view.bounds.size.width/2, yInputView);
。
问题是,您点击初始 UITextField 以外的文本字段(全名,请参阅上面 signupButtonTouchUpInside:
方法中的代码)并且 SignUpInputView 立即移动到屏幕顶部。
我错过了一些东西,但事情是在将 NSLayoutConstraints 从 BaseController 重构到 getter 属性方法之前它正在工作,因为两次添加约束的崩溃,以及其他一般隐藏的 alpha 属性操作。
在这种情况下,您根本不应该设置任何框架。添加子视图,并为其设置约束以设置其初始位置;为您要修改的任何约束设置属性。要为视图设置动画,请将这些约束的常量值更改为您想要的值,然后在动画块中调用 layoutIFNeeded。