[英]Subview (UILabel) doesn't respect the constraints when placed in superview (UITextView)
I tried my own "placeholder in a UITextView
" implementation. 我尝试了自己的“
UITextView
占位符”实现。
My approach was this: 我的方法是这样的:
I create a UILabel
in a UITextView
subclass, and I set the constraints of the UILabel
to match the size of its superview ( UITextView
). 我在
UITextView
子类中创建一个UILabel
,并设置UILabel
的约束以匹配其超级视图( UITextView
)的大小。
This is the code where I create the UILabel
and assign it to a class variable named placeholderLabel
in awakeFromNib()
: 这是我创建
UILabel
并将其分配给awakeFromNib()
名为placeholderLabel
的类变量的代码:
placeholderLabel = UILabel()
placeholderLabel.text = placeholder
placeholderLabel.numberOfLines = 0
placeholderLabel.lineBreakMode = .byWordWrapping
placeholderLabel.textAlignment = .left
The following code is where I add the UILabel
as a subview, and I set the constraints, again in awakeFromNib()
: 下面的代码是我将
UILabel
添加为子视图的地方,然后再次在awakeFromNib()
设置约束:
placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
placeholderLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: textContainerInset.left + 4).isActive = true
placeholderLabel.topAnchor.constraint(equalTo: topAnchor, constant: textContainerInset.top).isActive = true
placeholderLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: textContainerInset.right + 4).isActive = true
placeholderLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: textContainerInset.bottom).isActive = true
I also have a property where I set the placeholder's text, where I have a didSet
observer, which sets placeholderLabel
's text and then calls layoutIfNeeded()
in order to have the constraints recalculated in case the UILabel
extends to a second (or third, etc) row: 我还有一个属性,用于设置占位符的文本,具有
didSet
观察器,该观察器设置placeholderLabel
的文本,然后调用layoutIfNeeded()
以便在UILabel
扩展至第二(或第三)时重新计算约束。等)行:
var placeholder: String = "" {
didSet {
placeholderLabel.text = placeholder
layoutIfNeeded()
}
}
The issue is that I have the following result: 问题是我得到以下结果:
The UILabel
extends beyond it's superviews bounds (to the right), and it appears that it doesn't respect the constraints. UILabel
超出了它的超级视图范围(向右),并且似乎不遵守约束。 I run the visual debugger which confirmed the same thing: 我运行可视调试器,该调试器确认了同样的事情:
It seems that there is a width constraint which follows the UILabel
's content width instead of following the constraint I have set in place ( in this case it creates a width of 431 whereas the superview's width is 288 ). 似乎存在一个遵循
UILabel
的内容宽度的宽度约束,而不是遵循我已经设置的约束( 在这种情况下,它创建的宽度为431而超级视图的宽度为288 )。
Is there something that I miss? 我有什么想念的吗?
First of all you have to use a negative value for the right constraint's constant (or - to use a positive value - switch the items placeholderLabel.rightAnchor
/ rightAnchor
). 首先,您必须为负约束的常数使用负值(或-要使用正值-切换项目
placeholderLabel.rightAnchor
/ rightAnchor
)。
The real problem though is the fact that UITextView
is a subclass of UIScrollView
. 但是,真正的问题是
UITextView
是UIScrollView
的子类。 In your case adding the UILabel
with a large text as a subview and constraining its edges to the textview's edges results in the textview's contentSize
to grow. 在您的情况下,将带有大文本的
UILabel
添加为子视图,并将其边缘限制在textview的边缘,将导致textview的contentSize
增大。 The textview becomes horizontally scrollable. textview变为水平滚动。
Printing out the textview's contentSize
before and after adding the label results in different values for the width (before: 335.0, after: 505.0). 在添加标签之前和之后打印出textview的
contentSize
导致宽度的不同值(之前:335.0,之后:505.0)。
Proof: https://www.dropbox.com/s/eogvl2c5r76c6cl/example.mov?dl=0 证明: https : //www.dropbox.com/s/eogvl2c5r76c6cl/example.mov? dl =0
You could work around that problem by not creating the right but a width constraint instead: 您可以通过不创建正确的宽度约束来解决此问题:
// placeholderLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -(textContainerInset.right + 4)).isActive = true
placeholderLabel.widthAnchor.constraint(equalTo: widthAnchor, constant: -(textContainerInset.left + 4 + textContainerInset.right + 4)).isActive = true
正确的应该是负号
placeholderLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: - textContainerInset.right - 4).isActive = true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.