当键盘显示时,UIKit会发布UIKeyboardWillShowNotification
,并在键盘隐藏时发布UIKeyboardWillHideNotification
。这些通知包含了你需要正确动画化UITextField
所需的所有内容。
假设你的UITextField
存储在一个名为myTextField
的属性中。
首先,你需要在某个地方注册通知。你注册的位置取决于哪个对象负责移动myTextField
。在我的项目中,该字段的父视图负责此操作,并且由于我从一个nib文件中加载我的UI,我在父视图的awakeFromNib
方法中完成注册:
- (void)awakeFromNib
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillShowNotification object:nil];
}
如果你使用UIViewController
来移动字段,你可能希望在viewWillAppear:animated:
中执行。
你应该在dealloc
或viewWillDisappear:animated:
中取消注册:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
当然,棘手的部分在于keyboardWillHideOrShow:
方法。首先,我从通知中提取动画参数:
- (void)keyboardWillHideOrShow:(NSNotification *)note
{
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardFrame
是在全局坐标系中。我需要将该框架转换为与 myTextField.frame
相同的坐标系,并且 myTextField.frame
在 myTextField.superview
的坐标系中:
CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil]
接下来,我计算出我想要myTextField
移动到的位置。新框架的底部边缘应该与键盘框架的顶部边缘相等:
CGRect newTextFieldFrame = self.myTextField.frame;
newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;
最后,我使用与键盘相同的动画参数来将myTextField
动画到它的新框架中:
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.myTextField.frame = newTextFieldFrame;
} completion:nil];
}
这是完整的代码:
- (void)keyboardWillHideOrShow:(NSNotification *)note
{
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];
CGRect newTextFieldFrame = self.myTextField.frame;
newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.myTextField.frame = newTextFieldFrame;
} completion:nil];
}
UITabBar
。当键盘隐藏时,UITextField
会滑动到UITabBar
下面。为什么会这样? - Fred Collins