Swift UI TextView placeholder

There is no placeholder in UITextView! ??

When I wanted to make a twitter-like app, I wrote the code like textView.placeholder =" " like textfield. I got angry with Value of type'UITextView' has no member'placeholder'. Eh, there is no placeholder for textView ... So, let's somehow implement placeholder in textView.

This time, create a class called TextView that inherits the UITextView and add a UILabel to the TextView.

TextView.swift


class TextView: UITextView {
    
    public let placeholderLabel: UILabel = {
        let label = UILabel()
        label.textColor = .lightGray
        label.font = .systemFont(ofSize: 18)
        label.numberOfLines = 0
        return label
    }()

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        addSubview(placeholderLabel)
        
        placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
        let cons = [
            placeholderLabel.topAnchor.constraint(equalTo: topAnchor, constant: 8),
            placeholderLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5),
            placeholderLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -5),
        ]
        
        NSLayoutConstraint.activate(cons)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}

I defined TextView like this.

All you have to do now is display textView with ViewController!

ViewController.swift


class ViewController: UIViewController {

    let textView: TextView = {
        let textView = TextView()
        textView.placeholderLabel.text = "It's a placeholder"
        textView.font = .systemFont(ofSize: 18)
        return textView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(textView)
        textView.frame = .init(x: 0, y: 100, width: view.frame.size.width, height: view.frame.size.height-200)
    }
}

This looks good! However, if you leave it as it is, the characters you entered and the characters of placeholder Label will overlap. Well, as a result of thinking about what to do, I decided to use textViewDidChange (_ textView: UITextView) of UITextViewDelegate.

ViewController.swift


extension ViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        if textView.text.isEmpty {
            self.textView.placeholderLabel.alpha = 1
        } else {
            self.textView.placeholderLabel.alpha = 0
        }
    }
}

It's like this. Show placeholderLabel if textView.text is empty, otherwise hide placeholderLabel.

Summary

You have to write a lot of code just by implementing placehoder in textView lol Please let me know if there is an easier way to implement it!

Recommended Posts

Swift UI TextView placeholder
Swift UI 100 knocks
Starting with Swift Swift UI
Progress made with Swift UI
Photo library in Swift UI
[Swift UI] Use Map view
Create Master Detail in Swift UI
[Swift 5] Implement UI for review function
Implementing side menus in Swift UI
Customize View with View Modifier in Swift UI
(For beginners) Swift UI view element collection
I tried using Realm with Swift UI
Shiritori map app made with Swift UI