iOS 键盘消失后视图自动下移
iOS view move down automatically after keyboard disappear
我有一个 iPad 项目,在它的一个视图控制器中,面板视图中有两个 TextField(视图是在 Storyboard 中构建的)。我想要实现的是,当这些文本字段中的任何一个成为第一响应者(即键盘出现)时,面板视图将向上移动,如果键盘消失,它将向下移动到原始位置。
有一次我测试向上移动,我发现键盘消失后视图会自动移回原来的位置,但我没有写任何代码来做到这一点。
要上移的代码:
- (void)moveUpTextFields {
if ([self.emailTextField isFirstResponder] || [self.passwordTextField isFirstResponder]) {
CGRect frame = self.textFieldPanel.frame;
frame.origin.y -= 50;
self.textFieldPanel.frame = frame;
}
}
所以我想弄清楚这是怎么发生的,我应该如何实现我的目标(即如果键盘出现向上移动并返回到原始位置)?
更新:
为了实现我的目标,应该使用键盘通知。在 viewWillAppear
中注册这些通知
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
我很久以前在另一个项目中做过这个,只是一开始不记得了:(
你必须在通知中心监听键盘事件,幸运的是,这是几乎每个应用程序都需要的功能,所以检查这个:)
https://github.com/aceontech/KBKeyboardHandler
它完全可以满足您的需求,但我希望您能理解它的行为方式(注册系统通知)。
如果需要,也可以通过 cocoapods 获得
连播 'KBKeyboardHandler'
好的,奇怪的行为是因为当键盘出现或消失时,它会重新布局视图控制器的子视图并触发 -(void)viewDidLayoutSubviews
并将视图重新定位回 StoryBoard 的位置。如果视图是由代码创建的,那么这将不是问题。
除了为KeyBoard添加通知外,由于通知在布局子视图之前触发,我们还需要重新定位viewDidLayoutSubviews中的视图。
- (void)keyboardWillShow:(NSNotification *)notification {
CGSize keyboardSize = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
CGFloat y = self.view.frame.size.height - keyboardSize.height - self.textFieldPanel.frame.size.height - 5;
CGRect frame = self.textFieldPanel.frame;
panelViewYOffset = frame.origin.y - y;
frame.origin.y -= panelViewYOffset;
// Since it will layout subviews in viewDidLayout, why we set frame here?
// I tried to move this line, turns out the panel will move up but the animation is gone
// So this line will have a nice liner animation curve but I don't why, may be someone can explain it.
self.textFieldPanel.frame = frame;
}
- (void)keyboardWillHide:(NSNotification *)notification {
CGRect frame = self.textFieldPanel.frame;
frame.origin.y += panelViewYOffset;
self.textFieldPanel.frame = frame;
panelViewYOffset = 0;
}
在 viewDidLayoutSubviews 中:
- (void)viewDidLayoutSubviews {
CGRect frame = self.textFieldPanel.frame;
frame.origin.y -= panelViewYOffset;
self.textFieldPanel.frame = frame;
}
正如我提到的,这种方法仅适用于 StoryBoard(Interface Builder)中的视图,如果 self.textFieldPanel
是由代码创建的,则应删除 viewDidLayoutSubviews 中的代码。
我有一个 iPad 项目,在它的一个视图控制器中,面板视图中有两个 TextField(视图是在 Storyboard 中构建的)。我想要实现的是,当这些文本字段中的任何一个成为第一响应者(即键盘出现)时,面板视图将向上移动,如果键盘消失,它将向下移动到原始位置。
有一次我测试向上移动,我发现键盘消失后视图会自动移回原来的位置,但我没有写任何代码来做到这一点。
要上移的代码:
- (void)moveUpTextFields {
if ([self.emailTextField isFirstResponder] || [self.passwordTextField isFirstResponder]) {
CGRect frame = self.textFieldPanel.frame;
frame.origin.y -= 50;
self.textFieldPanel.frame = frame;
}
}
所以我想弄清楚这是怎么发生的,我应该如何实现我的目标(即如果键盘出现向上移动并返回到原始位置)?
更新:
为了实现我的目标,应该使用键盘通知。在 viewWillAppear
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
我很久以前在另一个项目中做过这个,只是一开始不记得了:(
你必须在通知中心监听键盘事件,幸运的是,这是几乎每个应用程序都需要的功能,所以检查这个:) https://github.com/aceontech/KBKeyboardHandler
它完全可以满足您的需求,但我希望您能理解它的行为方式(注册系统通知)。
如果需要,也可以通过 cocoapods 获得
连播 'KBKeyboardHandler'
好的,奇怪的行为是因为当键盘出现或消失时,它会重新布局视图控制器的子视图并触发 -(void)viewDidLayoutSubviews
并将视图重新定位回 StoryBoard 的位置。如果视图是由代码创建的,那么这将不是问题。
除了为KeyBoard添加通知外,由于通知在布局子视图之前触发,我们还需要重新定位viewDidLayoutSubviews中的视图。
- (void)keyboardWillShow:(NSNotification *)notification {
CGSize keyboardSize = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
CGFloat y = self.view.frame.size.height - keyboardSize.height - self.textFieldPanel.frame.size.height - 5;
CGRect frame = self.textFieldPanel.frame;
panelViewYOffset = frame.origin.y - y;
frame.origin.y -= panelViewYOffset;
// Since it will layout subviews in viewDidLayout, why we set frame here?
// I tried to move this line, turns out the panel will move up but the animation is gone
// So this line will have a nice liner animation curve but I don't why, may be someone can explain it.
self.textFieldPanel.frame = frame;
}
- (void)keyboardWillHide:(NSNotification *)notification {
CGRect frame = self.textFieldPanel.frame;
frame.origin.y += panelViewYOffset;
self.textFieldPanel.frame = frame;
panelViewYOffset = 0;
}
在 viewDidLayoutSubviews 中:
- (void)viewDidLayoutSubviews {
CGRect frame = self.textFieldPanel.frame;
frame.origin.y -= panelViewYOffset;
self.textFieldPanel.frame = frame;
}
正如我提到的,这种方法仅适用于 StoryBoard(Interface Builder)中的视图,如果 self.textFieldPanel
是由代码创建的,则应删除 viewDidLayoutSubviews 中的代码。