代码之家  ›  专栏  ›  技术社区  ›  Osama Naeem

UITextView高度在键入/不使用情节提要时动态更改

  •  9
  • Osama Naeem  · 技术社区  · 7 年前

    我有这个UITextView&我希望它的高度在用户键入时动态变化。我想用编程的方式来做。我的UITextView位于另一个UIView之上。约束设置如下:

     addtextview.leadingAnchor.constraint(equalTo: addtasktextview.leadingAnchor, constant: 8).isActive = true
          addtextview.trailingAnchor.constraint(equalTo: addtasktextview.trailingAnchor, constant: -8).isActive = true
          addtextview.topAnchor.constraint(equalTo: addtasktextview.topAnchor, constant: 8).isActive = true
          addtextview.bottomAnchor.constraint(equalTo: addtasktextview.bottomAnchor, constant: -40).isActive = true
    

    有趣的是,我还在tableViewCells中使用textview,并通过使用此约束方法动态更改高度,但在这里它不起作用。 我希望文本视图的高度以向上移动的方式增加。因此,当新行开始时,顶部应移动,保持下面的间距。

    我该怎么做?我们将不胜感激。

    enter image description here

    更新:我能够在下面的@Supporter of truth的答案中使用它。通过查找textview正常高度和newSize之间的差异,我还能够动态更改父UIView容器高度。然后将该差值添加到容器的高度。

    3 回复  |  直到 7 年前
        1
  •  15
  •   Upholder Of Truth Yawar    7 年前

    首先,确保您的类采用UITextViewDelegate协议,以便在文本发生如下更改时通知您:

    class MyClass: UIViewContoller, UITextViewDelegate
    

    接下来,在类中的某个位置定义此变量,以便跟踪约束中的高度:

    var textHeightConstraint: NSLayoutConstraint!
    

    接下来添加以下约束并将其激活:

        self.textHeightConstraint = addtextview.heightAnchor.constraint(equalToConstant: 40)
        self.textHeightConstraint.isActive = true
    

    (如果在viewDidLoad中不执行此操作,则需要将textHeightConstraint设置为可选)

    下一步订阅委托(如果尚未完成):

    addTextView.delegate = self
    

    添加此函数可重新计算高度约束:

    func adjustTextViewHeight() {
        let fixedWidth = addtextview.frame.size.width
        let newSize = addtextview.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
        self.textHeightConstraint.constant = newSize.height
        self.view.layoutIfNeeded()
    }
    

    接下来,在创建约束后添加对该函数的调用,以设置初始大小:

    self.adjustTextViewHeight()
    

    最后,添加此方法以在文本更改时调整高度:

    func textViewDidChange(_ textView: UITextView) {
        self.adjustTextViewHeight()
    }
    

    为了避免混淆,这里有一个UIViewController子类中的最小示例:

    class ViewController: UIViewController, UITextViewDelegate {
        @IBOutlet var textView: UITextView!
        @IBOutlet var textHolder: UIView!
    
        var textHeightConstraint: NSLayoutConstraint!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            textView.leadingAnchor.constraint(equalTo: textHolder.leadingAnchor, constant: 8).isActive = true
            textView.trailingAnchor.constraint(equalTo: textHolder.trailingAnchor, constant: -8).isActive = true
            textView.topAnchor.constraint(equalTo: textHolder.topAnchor, constant: 8).isActive = true
            textView.bottomAnchor.constraint(equalTo: textHolder.bottomAnchor, constant: -40).isActive = true
    
            self.textHeightConstraint = textView.heightAnchor.constraint(equalToConstant: 40)
            self.textHeightConstraint.isActive = true
    
            self.adjustTextViewHeight()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func textViewDidChange(_ textView: UITextView) {
            self.adjustTextViewHeight()
        }
    
        func adjustTextViewHeight() {
            let fixedWidth = textView.frame.size.width
            let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
            self.textHeightConstraint.constant = newSize.height
            self.view.layoutIfNeeded()
        }
    }
    
        2
  •  6
  •   nCr78 Guy Daher    6 年前

    在实现了从“真理拥护者”中选择答案的解决方案后,我想知道如何消除由于高度约束的改变而带来的奇怪的文本底部偏移。

    一个简单的解决方案是在初始化开始时设置此选项:

    textView.isScrollEnabled = false
    

    最后,如果需要textview在特定高度后停止生长,可以将“adjustTextViewHeight”功能更改为:

    func adjustTextViewHeight() {
        let fixedWidth = growingTextView.frame.size.width
        let newSize = growingTextView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
        if newSize.height > 100 {
           growingTextView.isScrollEnabled = true
        }
        else {
           growingTextView.isScrollEnabled = false
           textViewHeightConstraint.constant = newSize.height
        }
       view.layoutSubviews()
    }
    

    希望这有帮助:)

        3
  •  3
  •   Miket25    7 年前

    有一个聪明的答案 here 在objective-c中,您可以在textView中检测换行符,并适当调整textView的帧。以下是swift版本:

    var previousPosition:CGRect = CGRect.zero
    func textViewDidChange(_ textView: UITextView) {
        let position:UITextPosition = textView.endOfDocument
        let currentPosition:CGRect = textView.caretRect(for: position)
        if(currentPosition.origin.y > previousPosition.origin.y){
            /*Update your textView's height here*/
            previousPosition = currentPosition
        }   
    }
    

    确保textView的视图控制器采用 UITextViewDelegate 和集合 self.textView.delegate = self

    演示 在这里,textView变小了,但它的增长取决于您的限制。 Demo