键盘WillShow中的平滑动画不能与UITextView一起工作。

问题描述 投票:0回答:1

对我有效的解决方案

经过几天的努力,我终于找到了视图动画问题的修复方法。对我来说 键盘将改变帧通知 的工作。解决方案在下面的帖子中讨论。

键盘出现时移动文本框

Gif

我在堆栈视图中嵌入了一堆视图,还有文本视图,我给文本视图的高度为<=120。我给文本视图的高度为<=120。在 keyboardWillShow 视图中,尽管添加了所需的代码,但它并没有产生动画。我玩过持续时间的值,但结果都一样。我想知道这是否是由于文本视图造成的?如何解决这个问题?

@objc func keyboardWillShow(notification:NSNotification) {

    guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }

    let keyboardScreenEndFrame = keyboardValue.cgRectValue
    let keyboardFrame = view.convert(keyboardScreenEndFrame, from: view.window)

    if #available(iOS 11.0, *) {
        scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardFrame.height - view.safeAreaInsets.bottom, right: 0)
    } else {
        scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardFrame.height, right: 0)
    }

    scrollView.scrollIndicatorInsets = scrollView.contentInset

    let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height + keyboardFrame.height - scrollView.bounds.size.height)
    scrollView.setContentOffset(bottomOffset, animated: true)

    UIView.animate(withDuration: 0.5, animations: { () -> Void in
        self.view.layoutIfNeeded()
    })
}

===

   extension FirstViewController: UITextViewDelegate {

    func textViewDidChange(_ textView: UITextView) {

        let estimatedSize = textView.sizeThatFits(textView.frame.size)

        if estimatedSize.height > textViewMaxHeight {
            if estimatedSize.height - textViewMaxHeight < textView.font!.lineHeight && !didExpandTextView {

                didExpandTextView = true

                var contentInset:UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: self.savedKbHeight, right: 0.0)

                if let v = self.tabBarController?.tabBar {
                    contentInset.bottom -= v.frame.height
                }

                scrollView.contentInset = contentInset
                scrollView.scrollIndicatorInsets = contentInset

                if textView.isFirstResponder {
                    let fr = textView.frame
                    scrollView.scrollRectToVisible(fr, animated: false)
                }
            }

            textView.isScrollEnabled = true
            textView.showsVerticalScrollIndicator = true

        } else {
            if let lineHeight = textView.font?.lineHeight, Int(estimatedSize.height / lineHeight) != numberOfLines {
                numberOfLines = Int(estimatedSize.height / textView.font!.lineHeight)

                var contentInset:UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: self.savedKbHeight, right: 0.0)

                print("contentInset: \(contentInset)")
                scrollView.contentInset = contentInset
                scrollView.scrollIndicatorInsets = contentInset

                if textView.isFirstResponder {
                    let fr = textView.frame
                    scrollView.scrollRectToVisible(fr, animated: false)
                }

                didExpandTextView = false
            }

            textView.isScrollEnabled = false
        }
    }

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}
ios swift uiscrollview uitextview uistackview
1个回答
1
投票

试试这个方法。

    func textViewDidChange(_ textView: UITextView) {

        let estimatedSize = textView.sizeThatFits(textView.frame.size)

        textView.isScrollEnabled = estimatedSize.height > textViewMaxHeight

        if !textView.isScrollEnabled {
            let maxBottom = self.view.frame.height - self.savedKbHeight

            // Use following line if you have Extended Edges set
            // let maxBottom = self.view.frame.height - self.savedKbHeight - topLayoutGuide.length - bottomLayoutGuide.length

            var r = self.textView.frame
            r.size.height = estimatedSize.height
            let tvBottom = self.scrollView.convert(r, to: self.view).maxX
            if tvBottom > maxBottom {
                self.scrollView.scrollRectToVisible(r, animated: true)
            }
        }
    }

编辑... 注: 这不是为了 生产就绪 代码。影响布局定位的东西很多,不能保证只是 "把这个丢进去 "就能在所有情况下发挥作用。

© www.soinside.com 2019 - 2024. All rights reserved.