如何在SWIFT中将textview的高度调整为他的内容?

时间:2015-04-03 12:11:10

标签: ios swift autolayout uitextview

在我的视图控制器中,我有一个UITextView。此textview填充了一个字符串。字符串可以是短的或长的。根据字符串的长度,textview的高度必须调整。 我使用故事板和自动布局。

我对textview的高度有些麻烦。

有时,高度完全适应文字。有时,不,文本在第一行被裁剪。下面,textview是黄色的。蓝色是滚动视图中的容器视图。紫色是一张照片的地方。

title1 title2

文本来自我的核心数据库,它们是字符串属性。 在屏幕1和屏幕2之间,唯一改变的是字符串 如果我在控制台中打印字符串,我有正确的文本:

my amazing new title

Another funny title for demo

我的textview的限制:

enter image description here

我不明白为什么我有两种不同的显示器。

修改

我尝试了@Nate建议,在viewDidLoad中,我补充道:

    myTextViewTitle.text="my amazing new title"

    myTextViewTitle.setContentHuggingPriority(1000, forAxis: UILayoutConstraintAxis.Vertical)
    myTextViewTitle.setContentCompressionResistancePriority(1000, forAxis: UILayoutConstraintAxis.Vertical)
    myTextViewTitle.setTranslatesAutoresizingMaskIntoConstraints(false)  

    let views = ["new_view": myTextViewTitle]
    var constrs = NSLayoutConstraint.constraintsWithVisualFormat("|-8-[new_view]-8-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)
    self.view.addConstraints(constrs)
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-8-[new_view]", options: NSLayoutFormatOptions(0), metrics: nil, views: views))
    self.myTextViewTitle.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[new_view(220@300)]", options: NSLayoutFormatOptions(0), metrics: nil, views: views))

没有结果。在界面构建器中为我的textview添加或不添加高度约束...

编辑2

我需要一个UITextView而不是UIlabel,因为使用了后退按钮,才能使用排除路径。

     let exclusionPathBack:UIBezierPath = UIBezierPath(rect: CGRect(x:backButton.bounds.origin.x, y:backButton.bounds.origin.y, width:backButton.bounds.width+10, height:backButton.bounds.height))
     myTextViewTitle.textContainer.exclusionPaths=[exclusionPathBack]

7 个答案:

答案 0 :(得分:40)

我找到了解决方案。

我专注于我的UITextView的高度,然后我读了一篇关于宽高比的文章。我想尝试,这有用!

所以在故事板中,我为textview添加了宽高比,并选中了“在构建时删除”选项。

在viewDidLayoutSubviews()中,我写道:

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()

    let contentSize = self.myTextViewTitle.sizeThatFits(self.myTextViewTitle.bounds.size)
    var frame = self.myTextViewTitle.frame
    frame.size.height = contentSize.height
    self.myTextViewTitle.frame = frame

    aspectRatioTextViewConstraint = NSLayoutConstraint(item: self.myTextViewTitle, attribute: .Height, relatedBy: .Equal, toItem: self.myTextViewTitle, attribute: .Width, multiplier: myTextViewTitle.bounds.height/myTextViewTitle.bounds.width, constant: 1)
    self.myTextViewTitle.addConstraint(aspectRatioTextViewConstraint!)

}

效果很好。

答案 1 :(得分:22)

首先,禁用UITextView的可滚动。 两个选项:

  1. 取消选中.xib中启用的滚动功能。
  2. [TextView setScrollEnabled:NO];
  3. 创建一个UITextView并将其与IBOutlet(TextView)连接。 添加具有默认高度的UITextView高度约束,将其与IBOutlet(TextViewHeightConstraint)连接。 当您异步设置UITextView的文本时,您应该计算UITextView的高度并将UITextView的高度约束设置为它。 示例代码:

    CGSize sizeThatFitsTextView = [TextView sizeThatFits:CGSizeMake(TextView.frame.size.width, MAXFLOAT)];
    
    TextViewHeightConstraint.constant = sizeThatFitsTextView.height; 
    

答案 2 :(得分:8)

在Swift 3.0中,tvHeightConstraint是主题TextView的高度约束(如果用于多个textview,则会将其添加到函数输入中):

func textViewDidChange(textView: UITextView) {

        let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
        if size.height != tvHeightConstraint.constant && size.height > textView.frame.size.height{
            tvHeightConstraint.constant = size.height
            textView.setContentOffset(CGPoint.zero, animated: false)
        }
    }

H / T到@cmi和@Pablo Ruan

答案 3 :(得分:5)

在swift 2.3中:

 func textViewDidChange(textView: UITextView) {

    let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.max))
    if size.height != TXV_Height.constant && size.height > textView.frame.size.height{
        TXV_Height.constant = size.height
        textView.setContentOffset(CGPointZero, animated: false)
    }
}

答案 4 :(得分:0)

为什么没有后退按钮的图像和文本的UILabel,并使用自动布局来定位它们?也许是黄色背景的第三个视图。

答案 5 :(得分:0)

我对一个非常相似的问题的简单解决方案:

我使用了行数设置为0的标签,而不是尝试使用文本字段或视图。然后我将前缘和后缘剪切到标签上。在我的情况下约束它们的宽度的容器,0作为约束的常量。问题是将行数设置为0以允许标签根据其内容增长或缩小。文字永远不会被切断,标签的高度永远不会超过其内容。对于我为宽度配置的所有不同大小类(在我的情况下为容器宽度)。经过IOS 8.0及更高版本的测试(同时确保'明确'未选中'首选宽度'所有标签的属性,标签宽度可根据不同的大小类进行调整) - 效果很好。

答案 6 :(得分:0)

我已经调整了你的代码并将它用于:layout子视图和textViewDidChange。非常感谢您在经过一个小时的故障排除后的第二天......

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()
    textViewDidChange(self.recordingTitleTV)


}

func textViewDidChange(_ textView: UITextView) {

    let contentSize = textView.sizeThatFits(textView.bounds.size)
    var frame = textView.frame
    frame.size.height = contentSize.height
    textView.frame = frame

    let aspectRatioTextViewConstraint = NSLayoutConstraint(item: textView, attribute: .height, relatedBy: .equal, toItem: textView, attribute: .width, multiplier: textView.bounds.height/textView.bounds.width, constant: 1)
    textView.addConstraint(aspectRatioTextViewConstraint)
}