📕
UITextViewにPlaceholderを表示する
はじめに
UITextViewには標準でPlaceholderが付いていないので、自分で実装するか、UITextView+Placeholderなどのライブラリを使用する必要があります。
VoicyではUITextView+Placeholderライブラリを使っていましたが、自分で実装できるものはライブラリを使わずに実装してライブラリを消したいと思ったので、消しました。
コード
import UIKit
class PlaceholderTextView: UITextView {
var placeholderLabel = UILabel()
@IBInspectable var placeholder: String? {
didSet {
placeholderLabel.text = placeholder
placeholderLabel.sizeToFit()
}
}
override var text: String! {
didSet {
textChanged()
}
}
override func layoutSubviews() {
super.layoutSubviews()
addSubview(placeholderLabel)
placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
placeholderLabel.textColor = .lightGray
placeholderLabel.font = font
placeholderLabel.numberOfLines = 0
placeholderLabel.text = placeholder
let horizontalPadding = textContainer.lineFragmentPadding
NSLayoutConstraint.activate([
placeholderLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: textContainerInset.left + horizontalPadding),
placeholderLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -(textContainerInset.right + horizontalPadding)),
placeholderLabel.topAnchor.constraint(equalTo: topAnchor, constant: textContainerInset.top),
placeholderLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: -textContainerInset.bottom),
placeholderLabel.widthAnchor.constraint(equalTo: widthAnchor)
])
NotificationCenter.default.addObserver(self, selector: #selector(textChanged), name: UITextView.textDidChangeNotification, object: nil)
}
@objc func textChanged() {
placeholderLabel.alpha = text.isEmpty ? 1.0 : 0.0
}
}
解説
placeholderの値をstoryboardから指定できるようになっています。
placeholderが実際に表示される位置はtextContainerInsetとtextContainer.lineFragmentPaddingを使うことによって元々使っているUITextViewの設定通りの内側のpaddingを保ってくれます。
まとめ
自分で実装できそうなものはなるべくライブラリ無しで実装したいね
Discussion