处理UIKeyboardWillShowNotification以便在按下视图控制器时键盘已经启动?

时间:2015-11-02 20:13:47

标签: ios cocoa-touch keyboard autolayout nsnotificationcenter

通常,如果您将UITextField设置为viewDidLoadviewWillAppear中的第一响应者,则当视图控制器被推入导航堆栈时,您将获得一个动画,其中视图控制器从右侧滑入键盘已经向上(即没有双动画):

  

enter image description here
   理想动画(250毫秒)

然而,当我use auto layout and control the layout of my view depending on the keyboard size时,它会导致奇怪的动画。在这种情况下,我的按钮对superview的底部有一个约束,我在键盘通知事件中更新了它的常量属性。

  

enter image description here
  越野车动画(250毫秒)

(注意按钮,占位符和标签在推送期间如何向上设置动画。还要注意光标如何从占位符文本下方开始并向上浮动直到它到达占位符。)

基本问题似乎是当触发通知时,它已经在动画块(动画导航控制器的动画块)中,然后在现有动画块中触发另一个动画块(即{{1}所以auto layout changes are animated)。

当然我可以在 viewDidAppear 中调用yesFirstResponder,但之后我会得到两个动画。我想利用键盘已启动的行为,以便界面看起来更具响应性(理想情况下为keeping it near 250 ms)。

  

enter image description here
  双动画(600毫秒)

如何以这样的方式处理UIKeyboardWillShowNotification:当用户点击UITextField并且在推动视图控制器时,使用上面的理想动画时,它将同时工作?

理想的解决方案:

  • Apple会在通知字典中提供另一个值,例如shouldAnimate,它会告诉您在处理通知时是否应该使用UIAnimation块。例如:在此次推送的情况下,它会发送 false ,但如果用户只是点击文本字段,则会发送 true

Hacky的解决方法:

  • 不要立即在viewDidLoad中设置becomeFirstReponder,而是以任意延迟调用它。这将导致不合需要的双重动画:首先视图控制器将从右侧滑入,然后然后键盘将出现。 (参见"双动画"以上动画为例。)
  • 通过查看通知的用户信息词典中的某个键(如self.view.layoutIfNeeded()在推送​​过程中UIKeyboardAnimationDurationUserInfoKey)和{{1}当用户点击UITextField时。如果动画是自定义的,Apple会更改动画等,这很容易破坏。
  • 0.350.25)和viewWillAppearpreventAnimationBlock = true)中设置一个标记。这似乎是最安全的方法,并产生我想要的精确动画。但是,保持状态是不可取的。

无法解决的解决方案:

  • viewDidLoad中的布局。在视图结束时加载,调用viewDidAppearpreventAnimationBlock = false,虽然此解决方案过去曾有效,但它不适用于上面的按钮示例。这将导致标签和文本视图无法正确设置动画,但该按钮仍将无法正确显示动画。
  • 尝试检查您是否已经处于动画块中:如果有办法知道我是否已经在动画块中,它可以解决我的问题;在这种情况下,我根本不会打电话给setNeedsLayout。我尝试使用these methods中的一个来计算它,但它们都没有用。可能是因为这是Apple在内部使用的某种隐藏/魔术动画块。
  • 尝试查看视图是否在屏幕上:对此视图的思考是视图会在屏幕外报告,因为尚未调用viewDidAppear,因此我不会将代码包装在一个动画块。但是,当您尝试查看视图是否在屏幕by looking at its window property上时,它会报告它在屏幕上,因此此解决方案无效。

参考:

活动顺序:

  1. viewDidLoad中
    • textField.becomeFirstResponder = true
    • 注册UIKeyboardWillShowNotification
  2. viewWillAppear中
  3. 触发UIKeyboardWillShowNotification
    • myConstraint.constant =来自通知的keyboardHeight
    • 在动画块内调用layoutIfNeeded
  4. viewDidAppear
  5. 用户点击textField时的通知信息:

      

    [UIKeyboardFrameBeginUserInfoKey:NSRect:{{0,736},{414,271}},
      UIKeyboardCenterEndUserInfoKey:NSPoint:{207,600.5},
      UIKeyboardBoundsUserInfoKey:NSRect:{{0,0},{414,271}},
      UIKeyboardFrameEndUserInfoKey:NSRect:{{0,465},{414,271}},
      UIKeyboardAnimationDurationUserInfoKey:0.25,
      UIKeyboardCenterBeginUserInfoKey:NSPoint:{207,871.5},
      UIKeyboardAnimationCurveUserInfoKey:7,
      UIKeyboardIsLocalUserInfoKey:1]

    在viewDidLoad中调用textField.becomeFirstResponder时的通知信息(即在推送期间):

      

    [ UIKeyboardFrameBeginUserInfoKey :NSRect:{{0, 465 },{414,271}},
      UIKeyboardCenterEndUserInfoKey:NSPoint:{207,600.5},
      UIKeyboardBoundsUserInfoKey:NSRect:{{0,0},{414,271}},
      UIKeyboardFrameEndUserInfoKey:NSRect:{{0,465},{414,271}},
       UIKeyboardAnimationDurationUserInfoKey 0.35
       UIKeyboardCenterBeginUserInfoKey :NSPoint:{207, 600.5 },
      UIKeyboardAnimationCurveUserInfoKey:7,
      UIKeyboardIsLocalUserInfoKey:1]

    (粗体差异。)

0 个答案:

没有答案