How can I add a placeholder in a UITextView
, similar to the one you can set for UITextField
, in Swift
?
Solution #1 - If you want the placeholder to disappear as soon as the user selects the text view: First set the UITextView to contain the placeholder text and set it to a light gray color to mimic the look of a UITextField 's placeholder text. Either do so in the viewDidLoad or upon the text view's creation.
Type placeholders is a new language feature introduced in Swift 5.6 (Xcode 13.3). The concept is straightforward. Type placeholders allow us to write types with type placeholders ( _ ) which directs the compiler to infer the type where _ is used.
The string that displays when there is no other text in the text field.
First set the UITextView to contain the placeholder text and set it to a light gray color to mimic the look of a UITextField 's placeholder text. Either do so in the viewDidLoad or upon the text view's creation. textView.text = "Placeholder" textView.textColor = UIColor.lightGray
Solution #1 - If you want the placeholder to disappear as soon as the user selects the text view: First set the UITextView to contain the placeholder text and set it to a light gray color to mimic the look of a UITextField 's placeholder text. Either do so in the viewDidLoad or upon the text view's creation.
func textViewDidBeginEditing (_ textView: UITextView) { cell.placeholderLabel.isHidden = !textView.text.isEmpty } no there is not any placeholder available for textview. you have to put label above it when user enter in textview then hide it or set by default value when user enters remove all values.
UITextViewDelegate 's methods will only be triggered by user interaction, but not programmatically. E.g. when you set a text view's text property programmatically, you'll have to set the placeholder's visibility yourself, because the delegate methods will not be called.
Updated for Swift 4
UITextView
doesn't inherently have a placeholder property so you'd have to create and manipulate one programmatically using UITextViewDelegate
methods. I recommend using either solution #1 or #2 below depending on the desired behavior.
Note: For either solution, add UITextViewDelegate
to the class and set textView.delegate = self
to use the text view’s delegate methods.
Solution #1 - If you want the placeholder to disappear as soon as the user selects the text view:
First set the UITextView
to contain the placeholder text and set it to a light gray color to mimic the look of a UITextField
's placeholder text. Either do so in the viewDidLoad
or upon the text view's creation.
textView.text = "Placeholder" textView.textColor = UIColor.lightGray
Then when the user begins to edit the text view, if the text view contains a placeholder (i.e. if its text color is light gray) clear the placeholder text and set the text color to black in order to accommodate the user's entry.
func textViewDidBeginEditing(_ textView: UITextView) { if textView.textColor == UIColor.lightGray { textView.text = nil textView.textColor = UIColor.black } }
Then when the user finishes editing the text view and it's resigned as the first responder, if the text view is empty, reset its placeholder by re-adding the placeholder text and setting its color to light gray.
func textViewDidEndEditing(_ textView: UITextView) { if textView.text.isEmpty { textView.text = "Placeholder" textView.textColor = UIColor.lightGray } }
Solution #2 - If you want the placeholder to show whenever the text view is empty, even if the text view’s selected:
First set the placeholder in the viewDidLoad
:
textView.text = "Placeholder" textView.textColor = UIColor.lightGray textView.becomeFirstResponder() textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument)
(Note: Since the OP wanted to have the text view selected as soon as the view loads, I incorporated text view selection into the above code. If this is not your desired behavior and you do not want the text view selected upon view load, remove the last two lines from the above code chunk.)
Then utilize the shouldChangeTextInRange
UITextViewDelegate
method, like so:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { // Combine the textView text and the replacement text to // create the updated text string let currentText:String = textView.text let updatedText = (currentText as NSString).replacingCharacters(in: range, with: text) // If updated text view will be empty, add the placeholder // and set the cursor to the beginning of the text view if updatedText.isEmpty { textView.text = "Placeholder" textView.textColor = UIColor.lightGray textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument) } // Else if the text view's placeholder is showing and the // length of the replacement string is greater than 0, set // the text color to black then set its text to the // replacement string else if textView.textColor == UIColor.lightGray && !text.isEmpty { textView.textColor = UIColor.black textView.text = text } // For every other case, the text should change with the usual // behavior... else { return true } // ...otherwise return false since the updates have already // been made return false }
And also implement textViewDidChangeSelection
to prevent the user from changing the position of the cursor while the placeholder's visible. (Note: textViewDidChangeSelection
is called before the view loads so only check the text view's color if the window is visible):
func textViewDidChangeSelection(_ textView: UITextView) { if self.view.window != nil { if textView.textColor == UIColor.lightGray { textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument) } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With