关于ios:TextField在编辑时附加到键盘 – 如何使ScrollView与编辑前相同?

TextField attach to keyboard while editing - how to make the ScrollView appear same as before editing?

我创建了新的Xcode单视图项目。在InterfaceBuilder中,我添加了一个uiscrollView来覆盖整个视图。在这个滚动视图上,我添加了一个uitextfield。生成的UI如下所示:enter image description here

请注意,此时滚动视图不会滚动,因为内容只占用视图的大小,而不会大于视图的大小。

现在,为了在编辑时将uitextfield放在键盘上,我按照Apple描述的方式管理键盘页面。在这样做之后,它给了我预期的行为,在编辑开始时将文本字段放在键盘正上方,如下面的屏幕截图所示:enter image description here

现在,在调用[textfield endEditing:YES]之后,键盘会隐藏起来,但文本字段不会返回到原来的位置。它将返回到其原始位置略高于其原始位置的位置,现在滚动视图将变为可滚动,就好像添加了一点高度:

enter image description here

注意上面屏幕截图中的滚动条!

我希望在编辑结束后(当键盘隐藏时)恢复视图的原始行为方面得到帮助,即文本字段返回到完全相同的位置,并且应该发生滚动,因为在编辑开始前不会发生滚动。

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


我认为苹果在这里指定的官方方式是保持这个功能正常工作的最简单和最好的方式。


1
2
3
You need adjust scrollview contentOffset textFieldDidBeginEditing and textFieldDidEndEditing.
or
One controller is available for scrollview auto scroll.

https://github.com/simonbs/bskeyboardcontrols


编辑时,将uitextfield和uitextview移到键盘之外:

对于非uitableviewcontrollers,将TPKeyboardAvoidingScrollView.mTPKeyboardAvoidingScrollView.h源文件放到项目中,将uiscrollview弹出到视图控制器的xib或故事板中,将滚动视图的类设置为tpkeyboardavoidingscrollview,并将所有控件放在该滚动视图中。您也可以通过编程方式创建它,而不使用XIB——只需使用tpkeyboardavoidingscrollview作为顶级视图。

要与uiTableViewController类一起使用,请将tpKeyboardAvoidingTableView.m和tpKeyboardAvoidingTableView.h放到项目中,并使uiTableView成为xib中的tpKeyboardAvoidingTableView。如果您的控制器没有使用XIB,我知道要使其UITableView成为自定义类并不容易:阻力最小的路径是为其创建XIB。

你可以从这里得到参考资料。

希望这有帮助。


看看你的代码,你不需要改变内容插入等,当试图定位滚动视图。您只需要修改内容偏移属性。

以下是修改后的代码:

1
2
3
4
@interface ViewController () {
UITextField *activeField;
CGPoint scrollViewOldPosition;
}

修改键盘如下:

1
2
3
4
5
6
7
8
9
10
11
12
// 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);
}

键盘将被隐藏方法:

1
2
3
4
5
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    self.scrollView.contentOffset = scrollViewOldPosition;
}


不是最好的代码,但是它有更多的特性可以使用,任何带有的东西都是全局变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//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;
    }
}


您也可以在不使用键盘通知的情况下执行类似的操作。正如您可能知道的,我们有TextField委托方法,我们可以使用这些方法设置ScrollView ContentOffset并获得相同的行为。

1
2
3
- (void)textFieldDidBeginEditing:(UITextField *)textField{
    scrollView.contentOffset = CGPointMake(0, textField.center.y-80); // you can change 80 to whatever which fits your needs
}

上面的方法设置滚动视图的contentOffset值,你的textFiled向上移动,而TextFieldresignFirstResponder调用下面的委托方法,你可以在这里设置contentOffset值。

1
2
3
- (void)textFieldDidEndEditing:(UITextField *)textField{
       scrollView.contentOffset = CGPointMake(0,-80);
}

注意:您需要使视图中的每个文本字段都将其委托作为您的UIViewController实例。你还需要你的UIViewController来采用UITextFieldDelegate