Last active
June 16, 2016 16:17
-
-
Save irace/6403a45cd90195c137d64bfa76defd5a to your computer and use it in GitHub Desktop.
`UITextView` should really just have this by default.
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
protocol TextContaining { | |
var isEmpty: Bool { get } | |
} | |
extension String: TextContaining { | |
} | |
extension Optional where Wrapped: TextContaining { | |
var isEmpty: Bool { | |
switch self { | |
case .Some(let someString): | |
return someString.isEmpty | |
default: | |
return true | |
} | |
} | |
} |
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
final class PlaceholderTextView: UITextView { | |
// MARK: - Public | |
var placeholder: String? { | |
set { | |
placeholderLabel.text = newValue | |
} | |
get { | |
return placeholderLabel.text | |
} | |
} | |
var placeholderColor: UIColor { | |
set { | |
placeholderLabel.textColor = newValue | |
} | |
get { | |
return placeholderLabel.textColor | |
} | |
} | |
// MARK: - Private | |
private var labelConstraints: [NSLayoutConstraint] = [] | |
private let placeholderLabel = UILabel().then { | |
$0.translatesAutoresizingMaskIntoConstraints = false | |
$0.lineBreakMode = .ByWordWrapping | |
$0.numberOfLines = 0 | |
$0.textColor = .lightGrayColor() | |
} | |
// MARK: - UITextView | |
override var font: UIFont? { | |
didSet { | |
placeholderLabel.font = font | |
} | |
} | |
override var text: String? { | |
didSet { | |
updatePlaceholderVisibility() | |
} | |
} | |
// MARK: - Initialization | |
override init(frame: CGRect, textContainer: NSTextContainer?) { | |
super.init(frame: frame, textContainer: textContainer) | |
addSubview(placeholderLabel) | |
[ | |
(UITextViewTextDidBeginEditingNotification, #selector(textFieldDidBeginEditing)), | |
(UITextViewTextDidEndEditingNotification, #selector(textFieldDidEndEditing)) | |
].forEach { name, selector in | |
NSNotificationCenter.defaultCenter().addObserver(self, selector: selector, name: name, object: self) | |
} | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
// MARK: - Actions | |
private dynamic func textFieldDidBeginEditing() { | |
placeholderLabel.hidden = true | |
} | |
private dynamic func textFieldDidEndEditing() { | |
updatePlaceholderVisibility() | |
} | |
// MARK: - UIView | |
override func updateConstraints() { | |
super.updateConstraints() | |
NSLayoutConstraint.deactivateConstraints(labelConstraints) | |
/* | |
These constraints are probably not totally comprehensive but should work fine in most cases (e.g. where the | |
text view is taller than the placeholder label). | |
Don’t pin to the edges because otherwise the scroll view’s content size will be impacted by the label. | |
*/ | |
labelConstraints = [ | |
placeholderLabel.centerXAnchor.constraintEqualToAnchor(centerXAnchor), | |
placeholderLabel.widthAnchor.constraintEqualToAnchor(widthAnchor, constant: -(textContainerInset.left + textContainerInset.right)), | |
placeholderLabel.topAnchor.constraintEqualToAnchor(topAnchor, constant: textContainerInset.top), | |
] | |
NSLayoutConstraint.activateConstraints(labelConstraints) | |
} | |
// MARK: - Private | |
private func updatePlaceholderVisibility() { | |
placeholderLabel.hidden = !text.isEmpty | |
} | |
} |
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
/// https://github.com/devxoul/Then | |
protocol Then { | |
} | |
extension Then { | |
public func then(@noescape block: Self -> Void) -> Self { | |
block(self) | |
return self | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment