Swift
UITextView
Placeholder
iOS Development
SwiftUI

Add placeholder text inside UITextView in Swift?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

To enhance user interaction within iOS applications, it's essential to provide clear and intuitive design elements. One such feature is the use of placeholder text within text input fields. While UITextField in Swift provides a straightforward way to add placeholder text, UITextView requires a bit more work as it does not come natively with placeholder support. This article discusses several strategies to implement placeholder text in UITextView.

Understanding UITextView

UITextView is a powerful view component in UIKit that supports multiline text entry, allowing users to input and edit text easily. Unlike UITextField, UITextView is more versatile, offering capabilities like text styling and layout adjustment.

Adding Placeholder Text to UITextView

To simulate placeholder functionality in a UITextView, you need to work around its lack of native placeholder support by implementing custom logic. Here are key approaches to dictate its behavior:

Method 1: Using Delegate Methods

By utilizing the UITextViewDelegate methods, you can determine when to display or hide placeholder text based on user interactions, such as when the user begins or ends editing the text view.

swift
1import UIKit
2
3class ViewController: UIViewController, UITextViewDelegate {
4
5    let textView: UITextView = {
6        let tv = UITextView()
7        tv.translatesAutoresizingMaskIntoConstraints = false
8        tv.text = "Enter your text here..."
9        tv.textColor = UIColor.lightGray
10        return tv
11    }()
12
13    override func viewDidLoad() {
14        super.viewDidLoad()
15        
16        view.addSubview(textView)
17        textView.delegate = self
18        
19        // Layout textView
20        NSLayoutConstraint.activate([
21            textView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
22            textView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
23            textView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8),
24            textView.heightAnchor.constraint(equalToConstant: 200)
25        ])
26    }
27
28    func textViewDidBeginEditing(_ textView: UITextView) {
29        if textView.textColor == UIColor.lightGray {
30            textView.text = nil
31            textView.textColor = UIColor.black
32        }
33    }
34
35    func textViewDidEndEditing(_ textView: UITextView) {
36        if textView.text.isEmpty {
37            textView.text = "Enter your text here..."
38            textView.textColor = UIColor.lightGray
39        }
40    }
41}

Explanation

  • Initialization: The textView is initialized with a default placeholder text and light gray color.
  • textViewDidBeginEditing: Clears the placeholder and sets text color to black when the text view becomes the first responder.
  • textViewDidEndEditing: Restores the placeholder text when the text view loses focus and no input was made.

Method 2: Using Subclassing

Subclass UITextView to create a custom component with integrated placeholder support.

swift
1import UIKit
2
3class PlaceholderTextView: UITextView {
4
5    private let placeholderLabel: UILabel = {
6        let label = UILabel()
7        label.textColor = UIColor.lightGray
8        label.numberOfLines = 0
9        label.isUserInteractionEnabled = false
10        return label
11    }()
12    
13    var placeholder: String? {
14        didSet {
15            placeholderLabel.text = placeholder
16            placeholderLabel.sizeToFit()
17        }
18    }
19
20    override init(frame: CGRect, textContainer: NSTextContainer?) {
21        super.init(frame: frame, textContainer: textContainer)
22        setupPlaceholder()
23    }
24
25    required init?(coder: NSCoder) {
26        fatalError("init(coder:) has not been implemented")
27    }
28
29    private func setupPlaceholder() {
30        addSubview(placeholderLabel)
31        
32        placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
33        NSLayoutConstraint.activate([
34            placeholderLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 4),
35            placeholderLabel.topAnchor.constraint(equalTo: topAnchor, constant: 8),
36            placeholderLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -4)
37        ])
38        
39        delegate = self
40        textColor = UIColor.black
41        backgroundColor = UIColor.white
42        updatePlaceholderVisibility()
43    }
44
45    func updatePlaceholderVisibility() {
46        placeholderLabel.isHidden = !text.isEmpty
47    }
48}
49
50extension PlaceholderTextView: UITextViewDelegate {
51    
52    func textViewDidChange(_ textView: UITextView) {
53        updatePlaceholderVisibility()
54    }
55}

Explanation

  • Placeholder Label: A UILabel is used to simulate placeholder text within the text view.
  • Placeholder Dynamics: The placeholder's visibility is toggled based on the text view's content.
  • Subview and Constraints: The placeholder label is added as a subview with leading, top, and trailing constraints.

Summary Table

MethodComponents UsedProsCons
DelegateUITextViewDelegate methodsSimplicity; no subclassing requiredLogic spread across the class
SubclassingCustom subclass of UITextViewEncapsulation; reusabilitySlightly more setup involved

Conclusion

Adding placeholder text to a UITextView requires some additional work compared to a UITextField, but the solutions provided offer robust methods for achieving this functionality. Whether using the delegate methods for a quick integration or subclassing UITextView for a reusable component, both approaches can enhance the user experience by guiding user input effectively. By integrating placeholder text into your UITextView, you provide users with a contextual prompt that improves usability and design consistency across your application.


Course illustration
Course illustration

All Rights Reserved.