简体   繁体   English

子视图(UILabel)放置在超级视图(UITextView)中时不遵守约束

[英]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 . 但是,真正的问题是UITextViewUIScrollView的子类。 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.

相关问题 将 UILabel 作为子视图添加到 UITextView 时的不明确约束 - Ambiguous constraints when adding UILabel as subview to UITextView 将UILabel作为子视图添加到具有编程约束的UITextView时,如何停止“内容大小”约束 - How can I stop the “content size” constraints when adding a UILabel as a subview to a UITextView, with programmatic constraints 子视图相对于父视图的坐标 - coordinates of a subview with respect to superview of superview 点击子视图(UITextView)时,将调用超级视图的inputViewController - inputViewController of superview gets called when tapped on subview(UITextView) UITextView和UILabel子视图属性为零 - UITextView and UILabel Subview Properties are nil 在 UITextView 之上添加 UILabel 作为子视图 - Adding a UILabel as a subview on top of a UITextView UICollectionView作为子视图不会更新约束 - UICollectionView as a subview doesn't update constraints ScrollView中的视图不遵守约束 - Views in ScrollView doesn't respect constraints 动画UIView框架不遵守约束? - Animating UIView frame doesn't respect constraints? 触摸按钮(子视图)时,不要在超级视图上处理平移手势 - Don't handle pan gesture on superview when touchdown button (subview)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM