Ios 如何在SWIFT中调整文本视图的高度以适应其内容?
在我的视图控制器中,我有一个UITextView。此文本视图由字符串填充。字符串可以是短的,也可以是长的。根据字符串的长度,必须调整textview的高度。 我使用故事板和自动布局 我对文本视图的高度有一些问题 有时,高度会根据文本进行完美调整。有时,不,文本在第一行被裁剪。下面的文本视图是黄色的。蓝色是滚动视图中的containerview。紫色是拍照的地方 这些文本来自我的核心数据库,它们是字符串属性。 在屏幕1和屏幕2之间,唯一改变的是字符串。Ios 如何在SWIFT中调整文本视图的高度以适应其内容?,ios,swift,autolayout,uitextview,Ios,Swift,Autolayout,Uitextview,在我的视图控制器中,我有一个UITextView。此文本视图由字符串填充。字符串可以是短的,也可以是长的。根据字符串的长度,必须调整textview的高度。 我使用故事板和自动布局 我对文本视图的高度有一些问题 有时,高度会根据文本进行完美调整。有时,不,文本在第一行被裁剪。下面的文本视图是黄色的。蓝色是滚动视图中的containerview。紫色是拍照的地方 这些文本来自我的核心数据库,它们是字符串属性。 在屏幕1和屏幕2之间,唯一改变的是字符串。 如果我在控制台中打印字符串,我会得到正确的
如果我在控制台中打印字符串,我会得到正确的文本:
my amazing new title
Another funny title for demo
my textview的限制条件:
我不明白为什么我有两个不同的显示器
编辑
我尝试了@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))
没有结果。在interface builder中为我的textview添加或不添加高度约束
编辑2
我需要一个UIExtView而不是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]
为什么不为后退按钮设置一个图像,为文本设置一个UILabel,并使用autolayout来定位它们呢?还有黄色背景的第三个视图。我找到了一个解决方案 我专注于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的标签,而不是尝试使用文本字段或视图。然后,我将前缘和后缘裁剪到标签的容器上,在我的例子中,这些容器约束了标签的宽度,约束的常量为0。关键是将行数设置为0,以允许标签根据其内容增长或收缩。对于我为宽度配置的所有不同大小的类(在我的例子中是容器宽度),文本永远不会被切碎,标签的高度永远不会超过其内容。针对IOS 8.0及更高版本进行测试(同时确保在标签宽度的所有标签的“首选宽度”属性旁边未选中“explicit”(显式),以针对不同的大小类别进行调整)-工作正常 首先,禁用UITextView的可滚动。 两种选择:
CGSize sizeThatFitsTextView = [TextView sizeThatFits:CGSizeMake(TextView.frame.size.width, MAXFLOAT)];
TextViewHeightConstraint.constant = sizeThatFitsTextView.height;
在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)
}
}
在Swift 3.0中,tvHeightConstraint是主题文本视图的高度约束(如果用于多个文本视图,则会将其添加到函数输入中):
H/T到@cmi和@Pablo Ruan我已经修改了您的代码,并将其用于两个方面:布局子视图和文本视图修改。非常感谢你让我在一个小时的故障排除后度过了美好的一天
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)
}
请尝试此处列出的解决方案:。方法是
sizeToFit
,但在您的情况下,您也需要约束。是否在UITextView中启用了滚动功能?@NateLee,此解决方案适用于UILabel。我使用UITextView。@在UITextViewsizeToFit中未启用abdullah滚动是UIView方法,UILabel和UITextView都是UIView的子类。这个解决方案也适用于你。是的,这是有原因的。因为我希望第一行在后退按钮的左边,第二行和第三行在按钮下面。在我的屏幕截图中,我还没有设置行高。这是一个很好的解决方案,我在textViewDidChange委托方法中使用textView.sizeThatFits
,效果非常好。回答得好,谢谢。我为这个问题尝试了很多不同的解决方案和外部库,这是唯一一个对我有效的。谢谢你,好先生。你也救了我一天@cmii谢谢。应该注意的是,如果你使用自动布局,故事板中的“滚动启用”选项会影响约束的布局方式,即使它没有明确显示这种关系。在取消勾选复选框之前,我一直在努力解决自动布局约束垃圾问题。在这之后,自动布局就完美地解决了。@dstepan感谢您将滚动设置为false的技巧!!!这真的很有帮助
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)
}