Created
November 27, 2018 10:41
-
-
Save hlung/c5dda3a0c2087e5ae6c1fce8822c4713 to your computer and use it in GitHub Desktop.
A UITextView subclass with placeholder text support. Swift 4.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
/// A UITextView subclass with placeholder text support. | |
/// It uses another UILabel to show the placeholder, shown when text is empty. | |
class PlaceholderTextView: UITextView { | |
lazy var placeholderLabel: UILabel = { | |
let label = UILabel() | |
label.textColor = UIColor(white: 0.5, alpha: 0.85) | |
label.backgroundColor = .clear | |
return label | |
}() | |
override init(frame: CGRect, textContainer: NSTextContainer?) { | |
super.init(frame: frame, textContainer: textContainer) | |
setupNotificationObserver() | |
} | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
setupNotificationObserver() | |
} | |
deinit { | |
NotificationCenter.default.removeObserver(self) | |
} | |
private func setupNotificationObserver() { | |
NotificationCenter.default.addObserver(self, | |
selector: #selector(TextViewWithPlaceholder.textDidChangeHandler(notification:)), | |
name: UITextView.textDidChangeNotification, | |
object: self) | |
} | |
override func layoutSubviews() { | |
super.layoutSubviews() | |
if text.isEmpty { | |
placeholderLabel.copyProperties(from: self) | |
addSubview(placeholderLabel) | |
bringSubviewToFront(placeholderLabel) | |
} else { | |
placeholderLabel.removeFromSuperview() | |
} | |
} | |
@objc func textDidChangeHandler(notification: Notification) { | |
setNeedsLayout() | |
} | |
} | |
private extension UILabel { | |
/// Copies common properties from UITextView. You can add more. | |
func copyProperties(from textView: UITextView) { | |
frame = textView.bounds.inset(by: textView.textContainerInset) | |
lineBreakMode = textView.textContainer.lineBreakMode | |
textAlignment = textView.textAlignment | |
numberOfLines = textView.textContainer.maximumNumberOfLines | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment