I tried my own "placeholder in a UITextView
" implementation.
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
).
This is the code where I create the UILabel
and assign it to a class variable named placeholderLabel
in awakeFromNib()
:
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()
:
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:
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. 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 ).
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
).
The real problem though is the fact that UITextView
is a subclass of 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. The textview becomes horizontally scrollable.
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).
Proof: 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.