Edited at

UITextViewにプレースホルダーを設定できるようにする(Swift4)


はじめに

Obj-C時代から思っていましたが、UITextFieldにはデフォルトでプレースホルダーがあるのに、なぜUITextViewにはないのでしょうか…。

ということで、こちらの記事を参考にさせていただき、Swift4でUITextViewにプレースホルダーを実装します。


プレースホルダーの実装

@IBInspectable を使うことにより、ストーリーボード上で placeHolder の値を指定できるようにしています。

self.placeHolderLabel.textColor の値が中途半端なのは、UITextFieldのデフォルト値がそのようになっているためです。


PlaceHolderTextView.swift

import UIKit

@IBDesignable class PlaceHolderTextView: UITextView {
// MARK: Properties

/// プレースホルダー
@IBInspectable var placeHolder: String = "" {
didSet {
self.placeHolderLabel.text = self.placeHolder
self.placeHolderLabel.sizeToFit()
}
}

/// [プレースホルダー]ラベル
private lazy var placeHolderLabel: UILabel = UILabel(frame: CGRect(x: 6.0,
y: 6.0,
width: 0.0,
height: 0.0))

// MARK: Initializers

deinit {
NotificationCenter.default.removeObserver(self)
}

// MARK: View Lifecycle

override func awakeFromNib() {
super.awakeFromNib()

configurePlaceHolder()
changeVisiblePlaceHolder()
NotificationCenter.default.addObserver(self,
selector: #selector(textChanged),
name: .UITextViewTextDidChange,
object: nil)
}

// MARK: Private Methods

/// プレースホルダーを構築する
private func configurePlaceHolder() {
self.placeHolderLabel.lineBreakMode = .byWordWrapping
self.placeHolderLabel.numberOfLines = 0
self.placeHolderLabel.font = self.font
self.placeHolderLabel.textColor = UIColor(red: 0.0,
green: 0.0,
blue: 0.0980392,
alpha: 0.22)
self.placeHolderLabel.backgroundColor = .clear
self.addSubview(placeHolderLabel)
}

/// プレースホルダーの表示/非表示を切り替える
private func changeVisiblePlaceHolder() {
if self.placeHolder.isEmpty || !self.text.isEmpty {
self.placeHolderLabel.alpha = 0.0
} else {
self.placeHolderLabel.alpha = 1.0
}
}

/// テキスト変更
///
/// - Parameter notification: 通知
@objc private func textChanged(notification: NSNotification?) {
changeVisiblePlaceHolder()
}