如何设置UITextView中的文本字段在键盘出现时上下移动?

时间:2014-04-01 11:59:35

标签: ios objective-c xcode ios7

我在应用中设置了一个UITextView,我希望每当用户键入并进入键盘行时,文本就会反弹一行,以便用户可以继续输入...

我怎样才能做到这一点?我在Interface Builder中添加了textView

enter image description here

4 个答案:

答案 0 :(得分:5)

这相当复杂。

我在github上的一个名为#34; RandomBlobs"的项目中写了如何做到这一点。 (链接)。

该项目包括使用所述技术的工作代码。

以下是该项目的文章:

转换视图以为键盘腾出空间

在应用程序中使用输入文本字段(UITextFieldUITextView)时,点击文本字段会使iOS键盘从屏幕底部生成动画。对于像UITableViewController这样的一些情况,系统将内容向上移动以为键盘腾出空间,但在大多数情况下它没有,并且您自己处理了这个问题。坦率地说,这样做很痛苦。您必须考虑到键盘高度因不同国家/地区和语言,屏幕和屏幕方向而异,并且也可能随操作系统版本而变化。 Apple也可以改变键盘动画的时间。

正确处理此问题涉及几个步骤。具体细节取决于您的应用程序是使用AutoLayout还是旧的" struts和spring"风格调整规则。

此应用程序使用struts和spring,并通过更改视图框架来移动视图。如果你使用AutoLayout,你移动视图的细节会略有不同,但基本思路是一样的。

当您收到UIKeyboardWillShowNotification时,它会包含指向NSNotification对象的指针。通知对象包括一个可选的userInfo属性,该属性可以包含一个字典,其中包含有关通知的更多信息。在键盘通知的情况下,userInfo块包含许多有用的键/值对,包括键盘的框架,屏幕坐标以及键盘显示/隐藏动画的持续时间。搜索字符串"键盘通知用户信息键"在Xcode文档中,了解有关用于键盘通知的hte用​​户词典的更多信息。

处理键盘动画需要几个步骤:

  1. 为2个不同的系统通知UIKeyboardWillShowNotificationUIKeyboardWillHideNotification添加观察者。如果您正在编写单视图应用程序(如RandomBlobs应用程序),则可以在viewDidLoad:animated方法中添加通知观察器。但是,如果您正在开发具有多个视图控制器的应用程序,则可能需要在viewWillAppear:animated方法中添加观察者。我喜欢使用新的基于块的addObserverForName:object:queue:usingBlock:方法。您还可以使用旧的`addObserver:selector:name:object:'方法,它要求您在观察者收到通知时调用第二个方法。两种观察者都会收到指向触发通知对象的指针,这对处理键盘通知非常重要。

  2. 添加相应的代码以移除您的UIKeyboardWillShowNotificationUIKeyboardWillHideNotification观察员。对于单视图应用程序,您可以在视图控制器的dealloc方法中执行此操作。对于具有多个视图控制器的应用,您可能希望在viewWillDisappear:animated方法中删除观察者。

  3. 为了弄清楚文本字段的移动距离,我们需要知道它的位置。为了那个,我们需要文本字段的位置。遗憾的是,键盘通知并未向我们提供有关即将编辑的字段的任何信息。因此,我们必须以某种方式确定哪个字段即将开始编辑。要做到这一点:

    一个。告诉编译器您的视图控制器符合UITextViewDelegate的{​​{1}}协议或UITextView的{​​{1}}协议。

    湾添加实例变量以记住即将编辑的视图。 (演示项目中的 textFieldToEdit 。)

    ℃。实施"开始编辑"视图类型的方法(UITextFieldDelegateUITextFieldtextViewShouldBeginEditing:UITextView。代码很简单:

    textFieldShouldBeginEditing:

    d。在IB中,将视图控制器设置为UITextField -(BOOL)textFieldShouldBeginEditing:(UITextField *)textField; { textFieldToEdit = textField; return YES; } 的代理。

  4. UITextView代码中,获取键盘框架和动画持续时间以及动画曲线。 UITextFieldUIKeyboardWillShowNotification都提供了这些值,但只需将您需要的信息记录到实例变量中就更简单了,然后将其用于{{的处理程序中。 1}}处理程序。

    一个。提取键盘的高度(从 UIKeyboardFrameBeginUserInfoKey 键/值对中提供的框架)并使用它来计算我们需要移动键盘的数量。我们需要在屏幕coorindates中找出输入字段底部的Y coorindate,然后找出我们需要将视图向上移动以完全展开视图的最小值。 (请参阅演示应用程序中的代码,如下所示)。在演示应用中,我们将此值保存到实例变量 keyboardShiftAmount

    湾获取动画持续时间(来自 UIKeyboardAnimationDurationUserInfoKey 键/值对)并将其保存到float实例变量(在示例应用程序中称为keyboardSlideDuration)

    ℃。将键盘动画曲线(从 UIKeyboardAnimationCurveUserInfoKey 键/值对)保存到演示项目中的实例变量(称为 keyboardAnimationCurve )中。键盘动画曲线是 UIViewAnimationCurve 类型的变量,范围从0到4,并由较旧的UIKeyboardWillShowNotification ... UIKeyboardWillHideNotification样式的视图动画使用。我们想要使用更新的基于块的UIView动画方法UIKeyboardWillHideNotification,它采用枚举类型 UIViewAnimationOptions 的动画曲线信息。 UIViewAnimationOptions 中的动画曲线信息向上移动了16位,因此我们必须将指定的 UIViewAnimationCurve 转换为相应的 UIViewAnimationOptions 位标记。将值移位16位(如代码所示)

  5. 通过指定键盘移位量的(负值)动画视图的帧,并使用我们在上面的步骤3中获得的持续时间和动画曲线。一些开发人员只会转移正在编辑的字段。我认为这是令人困惑的,因为该字段将浮动并且不再处于相对于表单中其他字段的相同位置。相反,我通常会为视图控制器的整个内容视图设置动画。

  6. beginAnimations:context:代码中,执行上一步的相反操作,并再次为视图设置动画。由于我们在commitAnimations处理程序中保存了键盘移位量,动画持续时间和动画曲线,因此此代码非常简单。

  7. 将所有这些放在一起,让我们看看我们的演示应用程序中的代码,它为animateWithDuration:delay:options:animations:completion:UIKeyboardWillHideNotification观察者添加了观察者:

    UIKeyboardWillShowNotification

    请注意,如果您使用的是AutoLayout,则还有其他几个步骤,代码略有不同。您需要在视图上添加一个顶部约束,从顶部布局指南中添加一个常量偏移,并在底部布局指南中添加底部约束到视图。然后,您需要将此链接链接到视图控制器中的IBOutlets,以便您可以在代码中更改其偏移量。在上面的代码中,我们使用了名为 keyboardConstraint keyboardBottomConstraint

    的IBOutlet约束

答案 1 :(得分:1)

阅读有关处理键盘here的Apple文档。

答案 2 :(得分:0)

收听UIKeyboardWillShowNotificationUIKeyboardWillHideNotification通知,并相应调整UITextView的大小。

- (void)dealloc {
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)viewDidLoad {
  [super viewDidLoad];
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(keyboardWillShow:)
                                               name:UIKeyboardWillShowNotification
                                             object:nil];
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(keyboardWillHide:)
                                               name:UIKeyboardWillHideNotification
                                             object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
  CGSize keyboardSize = [[[notification.userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue] size];
  self.textView.frame = CGRectMake(tv.frame.origin.x, tv.frame.origin.y, tv.frame.size.width, self.view.frame.size.height - keyboardSize.height);
}

- (void)keyboardWillHide:(NSNotification *)notification {
  self.textView.frame = self.view.bounds;
}

答案 3 :(得分:0)

添加观察者:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillChange:)
                                             name:UIKeyboardWillChangeFrameNotification
                                           object:nil];

然后:

- (void)keyboardWillChange:(NSNotification *)notification
{
    NSDictionary *userInfo = notification.userInfo;

    CGRect endFrame = [[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    endFrame = [self.view convertRect:endFrame fromView:nil];

    // yourView.rect = // endFrame...
}