2015-04-03 145 views
20

在我的视图控制器中,我有一个UITextView。该文本视图中填充了一个字符串。字符串可以是短或长。根据字符串的长度,textview的高度必须调整。 我使用故事板和自动布局。如何在SWIFT中将文本视图的高度调整为其内容?

我有一些与textview的高度的麻烦。

有时候,高度可以根据文本进行完美调整。有时,不,文本在第一行被裁剪。下面,textview是黄色的。蓝色是scrollview内的容器视图。紫色是一张照片的地方。

title1title2

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

my amazing new title 

Another funny title for demo 

我的TextView的约束:

enter image description here

我不明白为什么我有2个不同的显示器。

编辑

我试过@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([email protected])]", options: NSLayoutFormatOptions(0), metrics: nil, views: views)) 

没有结果。带或不带高度contraint增加了我在Interface Builder的TextView ...

EDIT 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] 
+0

尝试SOLU这里列出:http://stackoverflow.com/questions/16009405/uilabel-sizetofit-doesnt-work-with-autolayout-ios6。 'sizeToFit'方法是要走的路,但在你的情况下你也需要约束。 – 2015-04-03 12:36:29

+0

在UITextView中启用了滚动吗? – Abdullah 2015-04-03 15:43:25

+0

@NateLee,这个解决方案是针对UILabel的。我使用UITextView。 – cmii 2015-04-03 16:26:51

回答

37

我找到了解决方案。

我关注的是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!) 

} 

它完美。

+0

这是一个很好的解决方案,我在textViewDidChange委托方法中使用'textView.sizeThatFits',完美地工作。好的答案,谢谢 – Swinny89 2015-09-04 15:59:37

+0

我为这个问题尝试了很多不同的解决方案和外部库,这是唯一对我有用的解决方案。谢谢你,先生。 – Ces 2016-06-04 01:22:08

+0

感谢@cmii你救了我的一天..... – 2017-08-29 11:43:15

0

为什么没有用于后退按钮的图像和用于文本的UILabel,并使用autolayout来定位它们?也许是黄色背景的第三种观点。

+0

是的,有一个原因。这是因为我想在后退按钮的左边第一行,按钮下面的第二行和第三行。在我的截图中,我还没有设置线高。 – cmii 2015-04-06 16:51:08

0

我简单的解决方案,以一个非常类似的问题:

我使用的标签设置为0,而不是试图用文本字段或视图的行数。然后,我将前缘和后缘剪裁到标签的容器上,这些容器限制了它们的宽度,以0作为约束的常量。问题是将行数设置为0以允许标签根据其内容增长或缩小。对于我为宽度配置的所有不同大小类(我的情况下的容器宽度),文本不会被切碎,标签的高度也不会超过它们的内容。测试IOS 8.0和更高版本(还要确保'显式'未选中所有标签的'首选宽度'属性旁边的标签宽度以适应不同大小类别) - 完美地工作。

20

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

  1. 取消选中滚动在.xib中启用。
  2. [TextView setScrollEnabled:NO];

创建一个UITextView并将其与IBOutlet(TextView)连接。 使用默认高度添加UITextView高度约束,将其与IBOutlet(TextViewHeightConstraint)连接起来。 当你异步设置你的UITextView文本时,你应该计算UITextView的高度并设置UITextView的高度约束。 示例代码:

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

TextViewHeightConstraint.constant = sizeThatFitsTextView.height; 
+3

应当注意的是,如果你使用的自动布局中,“滚动启用”选择在故事板影响如何约束尽管它没有明确地表明这种关系,但它们都是布置好的。我在自动布局约束垃圾中挣扎,直到我取消勾选复选框。之后,自动布局解决了自己的问题。 – dstepan 2016-12-19 17:37:18

+0

@dstepan感谢您将该设置滚动为false的技巧!这真的帮助 – Hordaric 2017-03-19 13:24:15

+0

谢谢你,工作很棒! – 2017-10-05 06:21:38

5

在迅速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) 
    } 
} 
6

在夫特3.0,其中tvHeightConstraint是主体的TextView的高度约束(如果使用多个textviews,将其添加到功能的输入):

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阮

相关问题