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

Joh*_*igs 1 xcode objective-c ios ios7

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

我怎么能做到这一点?我textView在Interface Builder中添加了它.

在此输入图像描述

Dun*_*n C 5

这很复杂.

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

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

这是该项目的文章:

转换视图为键盘腾出空间

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

正确处理这涉及几个步骤.具体细节取决于您的应用程序是使用AutoLayout还是旧的"struts and springs"样式调整大小规则.

此应用程序使用支柱和弹簧,并通过更改视图的框架来移动视图.如果您使用AutoLayout,您移动视图的细节会略有不同,但基本思路是相同的.

收到a时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. 为了弄清楚移动文本字段的距离,我们需要知道它的位置.为了做到,我们需要的文本字段的位置.遗憾的是,键盘通知不会向我们提供有关即将编辑的字段的任何信息.因此,我们必须以某种方式确定哪个字段即将开始编辑.要做到这一点:

    一个.告诉编译器您的视图控制器符合正确的协议(a的UITextViewDelegate协议UITextViewUITextFieldDelegate协议UITextField.)

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

    C.为您的视图类型实现"开始编辑"方法(textViewShouldBeginEditing:对于a UITextViewtextFieldShouldBeginEditing:for UITextField).代码很简单:

        -(BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
        {
    
          textFieldToEdit = textField;
          return YES;
        }
    
    Run Code Online (Sandbox Code Playgroud)

    d.在IB中,将视图控制器设置为您UITextView或的代理UITextField.

  4. UIKeyboardWillShowNotification代码中,获取键盘框架和动画持续时间,以及动画曲线.这些值在UIKeyboardWillShowNotification和中提供UIKeyboardWillHideNotification,但通常只需将您需要的信息记录到实例变量中,然后将其用于UIKeyboardWillHideNotification处理程序的处理程序中.

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

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

    C.将键盘动画曲线(从UIKeyboardAnimationCurveUserInfoKey键/值对)保存到实例变量(在演示项目中称为keyboardAnimationCurve).键盘动画曲线是UIViewAnimationCurve类型的变量,范围从0到4,并由旧的beginAnimations:context:... commitAnimations样式的视图动画使用.我们想要使用更新的基于块的UIView动画方法animateWithDuration:delay:options:animations:completion:,该方法获取枚举类型UIViewAnimationOptions的动画曲线信息.UIViewAnimationOptions中的动画曲线信息向上移位16位,因此我们必须通过将值移位16位将指定的UIViewAnimationCurve转换为相应的UIViewAnimationOptions位标志(如代码所示)

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

  6. UIKeyboardWillHideNotification代码中,执行上一步的相反操作,然后再次向下查看动画.由于我们在UIKeyboardWillShowNotification处理程序中保存了键盘移位量,动画持续时间和动画曲线,因此此代码非常简单.

将所有这些放在一起,让我们看看我们的演示应用程序中的代码,它们为观察者UIKeyboardWillShowNotificationUIKeyboardWillHideNotification观察者添加观察者:

showKeyboardNotificaiton = [[NSNotificationCenter defaultCenter] addObserverForName: UIKeyboardWillShowNotification
  object: nil
  queue: nil
  usingBlock: ^(NSNotification *note)
  {
    //Get the keyboard frame from the notificaiton's userinfo dictionary (in non-rotated screen coordinates)
    CGRect keyboardFrame;
    NSDictionary* userInfo = note.userInfo;
    keyboardSlideDuration = [[userInfo objectForKey: UIKeyboardAnimationDurationUserInfoKey] floatValue];
    keyboardFrame = [[userInfo objectForKey: UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    keyboardAnimationCurve = [[userInfo objectForKey: UIKeyboardAnimationCurveUserInfoKey] integerValue]<<16;

    UIInterfaceOrientation theStatusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation];

    CGFloat keyboardHeight;

    //if we're in landscape, treat use the reported keyboard width as the height
    if UIInterfaceOrientationIsLandscape(theStatusBarOrientation)
      keyboardHeight = keyboardFrame.size.width;
    else
      keyboardHeight = keyboardFrame.size.height;

    CGRect fieldFrame = textFieldToEdit.bounds;
    fieldFrame = [self.view convertRect: fieldFrame fromView: textFieldToEdit];
    CGRect contentFrame = self.view.frame;
    CGFloat fieldBottom = fieldFrame.origin.y + fieldFrame.size.height;

    keyboardShiftAmount= 0;
    if (contentFrame.size.height - fieldBottom <keyboardHeight)
    {
      keyboardShiftAmount = keyboardHeight - (contentFrame.size.height - fieldBottom);
//----------------------------------------------------------------------------------------------
//This is the code to shift the view if we're using AutoLayout:
//    keyboardConstraint.constant -= keyboardShiftAmount;
//    keyboardBottomConstraint.constant += keyboardShiftAmount;
//    [self.view layoutIfNeeded];
//----------------------------------------------------------------------------------------------

      //----------------------------------------------------------------------------------------------
      //This is the code for handling the keyboard animations for strut-and-spring style view resizing
      [UIView animateWithDuration: keyboardSlideDuration
        delay: 0
        options: keyboardAnimationCurve
        animations:
        ^{
          CGRect frame = self.view.frame;
          frame.origin.y -= keyboardShiftAmount;
          self.view.frame = frame;
        }
        completion: nil
       ];
      //----------------------------------------------------------------------------------------------
    }
  }
];

hideKeyboardNotificaiton = [[NSNotificationCenter defaultCenter] addObserverForName: UIKeyboardWillHideNotification
  object: nil
  queue: nil
  usingBlock: ^(NSNotification *note)
{
  if (keyboardShiftAmount != 0)
  {
    //------------------------------------------------------------------------------------------
    //This is the code for animating the view back down for strut-and-spring style view resizing

    [UIView animateWithDuration: keyboardSlideDuration
      delay: 0
      options: keyboardAnimationCurve
      animations:
     ^{
       CGRect frame = self.view.frame;
       frame.origin.y += keyboardShiftAmount;
       self.view.frame = frame;
    //------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------
//This is the code to shift the view back down if we're using AutoLayout
//     keyboardConstraint.constant += keyboardShiftAmount;
//     keyboardBottomConstraint.constant -= keyboardShiftAmount;
//     [self.view setNeedsUpdateConstraints];
//     [viewToShift layoutIfNeeded];
//----------------------------------------------------------------------------------------------
     }
                     completion: nil
     ];
   }


}
];
Run Code Online (Sandbox Code Playgroud)

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