swift UIText键入时动态更改视图高度/不使用情节提要

wr98u20j  于 2023-04-28  发布在  Swift
关注(0)|答案(3)|浏览(117)

我有这个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,并通过使用这个约束方法动态地改变了高度,但在这里它不起作用。我希望textview的高度以这样一种方式增加,它向上移动。因此,当一个新的行开始时,顶部应该移动,保持下面的间距。
我该怎么做?帮助将不胜感激。

更新:我能够让它工作与@ upheder的真相的答案如下。我还能够通过查找textview正常高度和newSize之间的差异来动态更改父UIView容器高度。高度,然后将该差值添加到容器的高度。

dbf7pr2w

dbf7pr2w1#

首先,确保你的类采用UITextViewDelegate协议,这样当文本发生如下变化时,你就可以得到通知:

class MyClass: UIViewContoller, UITextViewDelegate

接下来,在类中的某个地方定义这个变量,以便您可以跟踪约束中的高度:

var textHeightConstraint: NSLayoutConstraint!

接下来,添加以下约束并激活它:

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

(if在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()
    }
}
gg0vcinb

gg0vcinb2#

在实现了“真理的支持者”中选择的答案的解决方案后,我想知道如何摆脱由于高度约束的改变而带来的奇怪的文本底部偏移。
一个简单的解决方案是在初始化开始时设置:

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()
}

希望这对你有帮助:)

vsnjm48y

vsnjm48y3#

在objective-c中有一个聪明的答案here,你可以检测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

Demo这里的textView是向下增长的,但要让它增长则是您的限制问题。

相关问题