Как рассчитать правильный набор содержимого клавиатуры для UIScrollView внутри модально представленного листа формы UIViewController - PullRequest
0 голосов
/ 11 декабря 2018

У меня возникла проблема, из-за которой использование convertRect для правильного отчета о любой позиции, используемой для вычисления contentInset, не работает в iOS 12. Этот подход использовался для работы в более ранних версиях iOS:

@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 голосов
/ 11 декабря 2018

Apple заявляет в своей документации:

Примечание. Прямоугольник, содержащийся в свойствах UIKeyboardFrameBeginUserInfoKey и UIKeyboardFrameEndUserInfoKey словаря userInfo, должен использоваться только для информации о размере, содержащейся в нем.Не используйте источник прямоугольника (который всегда {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
    }
}
...