可调整大小然后滚动的UITextView,例如Telegram

时间:2019-04-06 11:06:34

标签: ios swift autolayout uitextview

我想创建可以同时调整大小和滚动的UITextView,就像Telegram,Instagram或Whats App上的一样,允许UITextView最多扩展到8行,如果您向其中添加更多文本,则可以滚动能够使UITextView增长到5行,但是如果它们是更多文本,因为isScroll属性被禁用,我看不到

我的UITextView在UIView的内部,左右两个按钮,如果可能的话,我也希望通过限制来做到这一点,如果不能通过代码也可以的话

enter image description here

2 个答案:

答案 0 :(得分:2)

您可以通过以下步骤实现预期的结果:

  1. 将textView委托分配给您的控制器
  2. 默认禁用textView滚动
  3. 在textViewDidChange委托方法上,根据textView框架测量文本高度
  4. 为文本视图分配适当的高度,如果超出内容,则启用滚动显示(在您的情况下,最大高度为8行)

以下是我要附加的代码段,可能会对您有所帮助:

let commentViewMinHeight: CGFloat = 45.0 
let commentViewMaxHeight: CGFloat = 120.0 //In your case it should be 8 lines

func textViewDidChange(_ textView: UITextView) {
     //Calculate text height 
     let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude))

     textViewHeightConstraint.constant = size.height.clamped(to: commentViewMinHeight...commentViewMaxHeight)

     if textView.contentSize.height < commentViewMaxHeight {
        textView.setContentOffset(CGPoint.zero, animated: false)
        if textView.isScrollEnabled {
           textView.isScrollEnabled = false
        }
     } else {
            if !textView.isScrollEnabled {
                textView.isScrollEnabled = true
            }
     }
} 

extension Comparable {
    func clamped(to limits: ClosedRange<Self>) -> Self {
        return min(max(self, limits.lowerBound), limits.upperBound)
    }
}

答案 1 :(得分:1)

Sagar的答案很好,但我想对其进行一些增强并为其添加一些动画:

您需要的步骤

  • 为您的textView获取出口
  • 添加高度限制并为其指定出口
  • textView的实现textViewDidChange委托方法
  • textViewDidChange
    • 使用textView.sizeThatFits(size)
    • 计算新高度
    • 将高度约束常量设置为新高度
    • [library]为约束更改设置动画以更加用户友好

这是一个例子

class ViewController: UIViewController {

    @IBOutlet weak var textView: UITextView!
    @IBOutlet weak var textViewHeightConstraint: NSLayoutConstraint!

    let maxTextHeight:CGFloat = 200
    let minTextHeight:CGFloat = 50

    let animationDuration:Double = 0.3

    override func viewDidLoad() {
        super.viewDidLoad()
        textView.delegate = self
        resizeTextViewToFitText()
    }

    func resizeTextViewToFitText() {
        let size = CGSize(width: textView.frame.width, height: .infinity)
        let expectedSize = textView.sizeThatFits(size)
        self.textViewHeightConstraint.constant = max(min(expectedSize.height, self.maxTextHeight), self.minTextHeight)
        self.textView.isScrollEnabled = expectedSize.height > self.maxTextHeight
        UIView.animate(withDuration: animationDuration) {
            self.view.layoutIfNeeded()
        }
    }
}

extension ViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
       resizeTextViewToFitText()
    }
}