仅使用UIKeyboardWillChangeFrameNotification通知

时间:2014-10-11 16:09:12

标签: ios8 uikeyboard nsnotification iphone-softkeyboard

考虑键盘的新QuickType部分。

是否可以使用通知UIKeyboardWillChangeFrameNotification,

简单地"不打扰"年龄较大的" UIKeyboardWillShowNotification和UIKeyboardWillHideNotification?

测试似乎表明它完美运行,使用 ONLY keyboardFrameDidChange - 但我们可能会遗漏一些东西?

BTW这里有一个如何使用UIKeyboardWillChangeFrameNotification的例子https://stackoverflow.com/a/26226732/294884

1 个答案:

答案 0 :(得分:35)

在2018-05-25更新了Swift 4

这绝对是可能的,并且可以将您的代码减少一半。以下示例使用自动布局进行大量繁重工作。

NotificationCenter.default.addObserverForName(
    NSNotification.Name.UIKeyboardWillChangeFrame,
    object: nil,
    queue: nil
) { (notification) in
    guard let userInfo = notification.userInfo,
          let frameEnd = userInfo[UIKeyboardFrameEndUserInfoKey] as? CGRect,
          let animationCurveValue = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int,
          let animationCurve = UIViewAnimationCurve(rawValue: animationCurveValue),
          let animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval
    else { return }

    // Convert the frame rects you're interested in to a common coordinate space
    let keyboardRect = self.view.convert(frameEnd, from: nil)
    let formContainerRect = self.view.convert(self.formContainerView.frame, from: nil)

    // Calculate their intersection and adjust your constraints accordingly
    let intersection = keyboardRect.intersection(formContainerRect)
    if !intersection.isNull {
        // Some overlap
        // Just an example; what exactly you do here will vary
        self.formContainerBottomConstraint.constant = intersection.size.height
    } else {
        // No overlap
        // Reset your views to their default positions
        self.formContainerBottomConstraint.constant = 0
    }

    var options: UIViewAnimationOptions = []
    switch animationCurve {
    case .easeInOut:
        options.insert(.curveEaseInOut)
    case .easeIn:
        options.insert(.curveEaseIn)
    case .easeOut:
        options.insert(.curveEaseOut)
    case .linear:
        options.insert(.curveLinear)
    }
    // You may also want to add additional animation options; do that here
    options.insert(.preferredFramesPerSecond60)

    UIView.animateWithDuration(
        animationDuration,
        delay: 0,
        options: options,
        animations: {
            self.view.layoutIfNeeded()
        },
        completion: nil,
    )
}

self.formContainerBottomConstraint是一个NSLayoutConstraint,它将我(虚构)形式的底部绑定到我的视图底部。当键盘显示时,此代码会向上显示字段,当键盘消失时,该代码会向下显示。

所有这一切都可以在iOS< 8使用UIKeyboardWillShowNotificationUIKeyboardWillHideNotification的组合。但!正如您所说,iOS 8引入了QuickType部分,可以由用户折叠或展开。这个解决方案非常通用,可让您的应用程序响应操作系统引发的任何键盘更改。