TextField 在编辑时附加到键盘 - 如何使 ScrollView 看起来与编辑前一样?
TextField attach to keyboard while editing - how to make the ScrollView appear same as before editing?
我创建了新的 Xcode 单视图项目。在界面生成器中,我添加了一个 UIScrollView 来覆盖完整视图。在这个滚动视图上,我添加了一个 UITextField。结果 UI 看起来像这样:
请注意,此时滚动视图不会滚动,因为内容仅占用视图的大小,不会大于它。
现在为了在编辑时将 UITextField 置于键盘顶部,我按照 Apple 在 Managing The Keyboard 页面上描述的方式进行操作。这样做之后,它给了我预期的行为,在编辑开始时将文本字段带到键盘上方,如下面的屏幕截图所示:
现在,在调用 [textfield endEditing:YES]
后,键盘会自行隐藏,但文本框不会 return 回到原来的位置。它 return 到其原始位置上方一点的位置,现在滚动视图变得可滚动,就好像添加了很少的高度一样:
注意上面截图中的滚动条!
我需要帮助在编辑结束后(当键盘隐藏时)恢复视图的原始行为,即 return 的 textField 到完全相同的位置并且滚动应该发生,因为它在编辑之前没有发生开始。
您也可以在不使用键盘通知的情况下执行类似的操作。您可能知道我们有 TextField
委托方法,我们可以使用它们来设置 scrollView contentOffset 并获得相同的行为
- (void)textFieldDidBeginEditing:(UITextField *)textField{
scrollView.contentOffset = CGPointMake(0, textField.center.y-80); // you can change 80 to whatever which fits your needs
}
上面的方法设置 contentOffset
滚动视图的值并且你的 textFiled
向上移动,而 textField
resignFirstResponder
下面的委托方法被调用,你可以调回 contentOffset
值
- (void)textFieldDidEndEditing:(UITextField *)textField{
scrollView.contentOffset = CGPointMake(0,-80);
}
注意:您需要让视图中的每个文本字段都将其委托作为您的 UIViewController
实例。你还需要你的UIViewController
采纳UITextFieldDelegate
这不是有史以来最好的代码,但它有更多您可以使用的功能,任何带 _ 的都是全局变量
//Handle notification when keyboard appear
- (void)keyboardOnScreen:(NSNotification *)notification
{
if (_isKeyboardShow) {
return; //If keyboard is showing then return
}
_keyboardHeight = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
[self animateTextFieldUp: YES];
_isKeyboardShow = YES;
}
//Handle notification when keyboard hide
- (void)keyboardOffScreen:(NSNotification *)notification
{
if(!_isKeyboardShow) return;
[self animateTextFieldUp: NO];
_isKeyboardShow = NO;//Missed this line
}
//Push view up with animation when keyboard show
- (void) animateTextFieldUp: (BOOL) up
{
UITextField *textfield = [UIResponder currentFirstResponder];
CGPoint windowPoint = [textfield convertPoint:textfield.bounds.origin toView:self.view];
int movementDistance;
CGPoint point = [_mainScrollView contentOffset];
//Push up only when blocked by keyboard
if (windowPoint.y + textfield.frame.size.height >= self.view.frame.size.height - _keyboardHeight) {
movementDistance = windowPoint.y - (self.view.frame.size.height - _keyboardHeight) + textfield.frame.size.height + 10;
_oldMovementDistance = movementDistance;
int movement = (up ? -movementDistance : movementDistance);
[_mainScrollView setContentOffset:CGPointMake(0, point.y - movement) animated:YES];
}
else { //Push view down the same amount
int movement = (up ? -movementDistance : _oldMovementDistance);
[_mainScrollView setContentOffset:CGPointMake(0, point.y - movement) animated:YES];
_oldMovementDistance = 0;
}
}
You need adjust scrollview contentOffset textFieldDidBeginEditing and textFieldDidEndEditing.
or
One controller is available for scrollview auto scroll.
查看您的代码,在尝试定位滚动视图时不需要更改内容插图等。你只需要修改内容偏移属性.
修改后的代码如下:
@interface ViewController () {
UITextField *activeField;
CGPoint scrollViewOldPosition;
}
修改keyboardWasShow如下:
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGFloat someSpaceBetweenKeyBoardAndField = 20.0;
scrollViewOldPosition = self.scrollView.contentOffset;
self.scrollView.contentOffset = CGPointMake(0, kbSize.height - (self.view.frame.size.height - activeField.frame.origin.y - activeField.frame.size.height) + someSpaceBetweenKeyBoardAndField);
}
键盘将被隐藏方法:
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
self.scrollView.contentOffset = scrollViewOldPosition;
}
在编辑过程中将 UITextField 和 UITextView 移出键盘:
对于非 UITableViewControllers,将 TPKeyboardAvoidingScrollView.m
和 TPKeyboardAvoidingScrollView.h
源文件放入项目中,将 UIScrollView 弹出到视图控制器的 xib 或故事板中,将滚动视图的 class 设置为TPKeyboardAvoidingScrollView,并将所有控件放在该滚动视图中。您也可以在不使用 xib 的情况下以编程方式创建它 - 只需使用 TPKeyboardAvoidingScrollView 作为您的顶级视图。
为了与 UITableViewController classes 一起使用,将 TPKeyboardAvoidingTableView.m 和 TPKeyboardAvoidingTableView.h 放入您的项目中,并使您的 UITableView 成为 xib 中的 TPKeyboardAvoidingTableView。如果您的控制器没有使用 xib,我知道没有简单的方法可以使其 UITableView 成为自定义 class:阻力最小的途径是为其创建一个 xib。
您可以从here获得参考。
希望对您有所帮助。
我认为 Apple here 指定的官方方式是保持此功能正常运行的最简单和最佳方式。
我创建了新的 Xcode 单视图项目。在界面生成器中,我添加了一个 UIScrollView 来覆盖完整视图。在这个滚动视图上,我添加了一个 UITextField。结果 UI 看起来像这样:
请注意,此时滚动视图不会滚动,因为内容仅占用视图的大小,不会大于它。
现在为了在编辑时将 UITextField 置于键盘顶部,我按照 Apple 在 Managing The Keyboard 页面上描述的方式进行操作。这样做之后,它给了我预期的行为,在编辑开始时将文本字段带到键盘上方,如下面的屏幕截图所示:
现在,在调用 [textfield endEditing:YES]
后,键盘会自行隐藏,但文本框不会 return 回到原来的位置。它 return 到其原始位置上方一点的位置,现在滚动视图变得可滚动,就好像添加了很少的高度一样:
注意上面截图中的滚动条!
我需要帮助在编辑结束后(当键盘隐藏时)恢复视图的原始行为,即 return 的 textField 到完全相同的位置并且滚动应该发生,因为它在编辑之前没有发生开始。
您也可以在不使用键盘通知的情况下执行类似的操作。您可能知道我们有 TextField
委托方法,我们可以使用它们来设置 scrollView contentOffset 并获得相同的行为
- (void)textFieldDidBeginEditing:(UITextField *)textField{
scrollView.contentOffset = CGPointMake(0, textField.center.y-80); // you can change 80 to whatever which fits your needs
}
上面的方法设置 contentOffset
滚动视图的值并且你的 textFiled
向上移动,而 textField
resignFirstResponder
下面的委托方法被调用,你可以调回 contentOffset
值
- (void)textFieldDidEndEditing:(UITextField *)textField{
scrollView.contentOffset = CGPointMake(0,-80);
}
注意:您需要让视图中的每个文本字段都将其委托作为您的 UIViewController
实例。你还需要你的UIViewController
采纳UITextFieldDelegate
这不是有史以来最好的代码,但它有更多您可以使用的功能,任何带 _ 的都是全局变量
//Handle notification when keyboard appear
- (void)keyboardOnScreen:(NSNotification *)notification
{
if (_isKeyboardShow) {
return; //If keyboard is showing then return
}
_keyboardHeight = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
[self animateTextFieldUp: YES];
_isKeyboardShow = YES;
}
//Handle notification when keyboard hide
- (void)keyboardOffScreen:(NSNotification *)notification
{
if(!_isKeyboardShow) return;
[self animateTextFieldUp: NO];
_isKeyboardShow = NO;//Missed this line
}
//Push view up with animation when keyboard show
- (void) animateTextFieldUp: (BOOL) up
{
UITextField *textfield = [UIResponder currentFirstResponder];
CGPoint windowPoint = [textfield convertPoint:textfield.bounds.origin toView:self.view];
int movementDistance;
CGPoint point = [_mainScrollView contentOffset];
//Push up only when blocked by keyboard
if (windowPoint.y + textfield.frame.size.height >= self.view.frame.size.height - _keyboardHeight) {
movementDistance = windowPoint.y - (self.view.frame.size.height - _keyboardHeight) + textfield.frame.size.height + 10;
_oldMovementDistance = movementDistance;
int movement = (up ? -movementDistance : movementDistance);
[_mainScrollView setContentOffset:CGPointMake(0, point.y - movement) animated:YES];
}
else { //Push view down the same amount
int movement = (up ? -movementDistance : _oldMovementDistance);
[_mainScrollView setContentOffset:CGPointMake(0, point.y - movement) animated:YES];
_oldMovementDistance = 0;
}
}
You need adjust scrollview contentOffset textFieldDidBeginEditing and textFieldDidEndEditing.
or
One controller is available for scrollview auto scroll.
查看您的代码,在尝试定位滚动视图时不需要更改内容插图等。你只需要修改内容偏移属性.
修改后的代码如下:
@interface ViewController () {
UITextField *activeField;
CGPoint scrollViewOldPosition;
}
修改keyboardWasShow如下:
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGFloat someSpaceBetweenKeyBoardAndField = 20.0;
scrollViewOldPosition = self.scrollView.contentOffset;
self.scrollView.contentOffset = CGPointMake(0, kbSize.height - (self.view.frame.size.height - activeField.frame.origin.y - activeField.frame.size.height) + someSpaceBetweenKeyBoardAndField);
}
键盘将被隐藏方法:
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
self.scrollView.contentOffset = scrollViewOldPosition;
}
在编辑过程中将 UITextField 和 UITextView 移出键盘:
对于非 UITableViewControllers,将 TPKeyboardAvoidingScrollView.m
和 TPKeyboardAvoidingScrollView.h
源文件放入项目中,将 UIScrollView 弹出到视图控制器的 xib 或故事板中,将滚动视图的 class 设置为TPKeyboardAvoidingScrollView,并将所有控件放在该滚动视图中。您也可以在不使用 xib 的情况下以编程方式创建它 - 只需使用 TPKeyboardAvoidingScrollView 作为您的顶级视图。
为了与 UITableViewController classes 一起使用,将 TPKeyboardAvoidingTableView.m 和 TPKeyboardAvoidingTableView.h 放入您的项目中,并使您的 UITableView 成为 xib 中的 TPKeyboardAvoidingTableView。如果您的控制器没有使用 xib,我知道没有简单的方法可以使其 UITableView 成为自定义 class:阻力最小的途径是为其创建一个 xib。
您可以从here获得参考。
希望对您有所帮助。
我认为 Apple here 指定的官方方式是保持此功能正常运行的最简单和最佳方式。