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 到完全相同的位置并且滚动应该发生,因为它在编辑之前没有发生开始。

项目 URL:- https://github.com/therohansanap/keyboard.git

您也可以在不使用键盘通知的情况下执行类似的操作。您可能知道我们有 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.

https://github.com/simonbs/BSKeyboardControls

查看您的代码,在尝试定位滚动视图时不需要更改内容插图等。你只需要修改内容偏移属性.

修改后的代码如下:

@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.mTPKeyboardAvoidingScrollView.h 源文件放入项目中,将 UIScrollView 弹出到视图控制器的 xib 或故事板中,将滚动视图的 class 设置为TPKeyboardAvoidingScrollView,并将所有控件放在该滚动视图中。您也可以在不使用 xib 的情况下以编程方式创建它 - 只需使用 TPKeyboardAvoidingScrollView 作为您的顶级视图。

为了与 UITableViewController classes 一起使用,将 TPKeyboardAvoidingTableView.m 和 TPKeyboardAvoidingTableView.h 放入您的项目中,并使您的 UITableView 成为 xib 中的 TPKeyboardAvoidingTableView。如果您的控制器没有使用 xib,我知道没有简单的方法可以使其 UITableView 成为自定义 class:阻力最小的途径是为其创建一个 xib。

您可以从here获得参考。

希望对您有所帮助。

我认为 Apple here 指定的官方方式是保持此功能正常运行的最简单和最佳方式。