如何在模态显示的表单UIViewController

时间:2018-12-10 22:13:52

标签: ios swift keyboard uikit

我遇到一个问题,依靠convertRect正确地报告要用于计算contentInset的位置在iOS 12上不起作用。这种方法曾经在早期的iOS版本上起作用:< / p>

@objc func keyboardVisibilityChanged(notification: Notification) {
    guard let userInfo = notification.userInfo else {
        assertionFailure()
        return
    }

    let keyboardScreenEndFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
    let keyboardViewEndFrame = scrollView.convert(keyboardScreenEndFrame, from: view.window!)

    if notification.name == UIResponder.keyboardWillHideNotification {
        scrollView.contentInset = .zero
        scrollView.scrollIndicatorInsets = .zero
    } else {
        let insets = UIEdgeInsets(top: 0, left: 0, bottom: (keyboardViewEndFrame.origin.y - keyboardViewEndFrame.size.height) , right: 0)
        scrollView.contentInset = insets
        scrollView.scrollIndicatorInsets = insets
    }
}

但是,此代码虽然获得了非常接近的视觉效果,但并不精确,并且在iPhone(全屏显示模式)时也会中断。

Broken Inset

1 个答案:

答案 0 :(得分:0)

Apple states在其文档中:

  

注意:UIKeyboardFrameBeginUserInfoKey中包含的矩形   和userInfo的UIKeyboardFrameEndUserInfoKey属性   字典仅应用于其包含的尺寸信息。   请勿在以下位置使用矩形的原点(始终为{0.0,0.0})   矩形相交操作。因为键盘是动画的   到位后,键盘的实际边界矩形会改变   随着时间的流逝。

所以我想出了以下解决方案,这些解决方案似乎可以在iOS 12和11上很好地工作:

// MARK: - Keyboard Notifications
@objc func keyboardVisibilityChanged(notification: Notification) {
    if notification.name == UIResponder.keyboardWillHideNotification {
        scrollView.contentInset = .zero
        scrollView.scrollIndicatorInsets = .zero
    }
    else {
        guard let userInfo = notification.userInfo,
            let value = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue,
            let window = view.window else {
                assertionFailure()
                return
        }

        let keyboardScreenEndFrame = value.cgRectValue
        let viewFrameInWindowCoordinates = window.convert(view.frame, from: view.superview)
        let bottomEdgeOfViewInWindowBottomCoordinates = window.frame.maxY - viewFrameInWindowCoordinates.maxY
        let contentInsetBottom = keyboardScreenEndFrame.height - bottomEdgeOfViewInWindowBottomCoordinates

        let insets = UIEdgeInsets(top: 0, left: 0, bottom: contentInsetBottom, right: 0)
        scrollView.contentInset = insets
        scrollView.scrollIndicatorInsets = insets
    }
}