Created
October 4, 2018 17:30
-
-
Save spencerwhyte/3ec7581e9b1de60e2fea1e4534b9d894 to your computer and use it in GitHub Desktop.
Another feable attempt at trying to make a performant UITextView -- just not worth the trouble
This file contains hidden or 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
class FloatingTextView: UIControl, UITextViewDelegate { | |
var label: String? { | |
didSet { | |
floatingLabel.text = label | |
hintLabel.text = label | |
} | |
} | |
var text: String? { | |
didSet { | |
updateLabelVisibility() | |
textLabel.text = text | |
} | |
} | |
var floatingLabelColor: UIColor = UIColor.lightGray | |
var proxyInputAccessoryView: UIView? | |
weak var proxyTextViewDelegate: UITextViewDelegate? | |
private let floatingLabelPadding: CGFloat = 20 | |
private let floatingLabel: UILabel | |
private let hintLabel: UILabel | |
private let textLabel: UILabel | |
private var textView: UITextView? | |
private var lastHideFloatingLabel: Bool? = nil | |
init() { | |
floatingLabel = UILabel() | |
hintLabel = UILabel() | |
textLabel = UILabel() | |
super.init(frame: CGRect.zero) | |
setup() | |
setupConstraints() | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
func textViewDidChange(_ textView: UITextView) { | |
text = textView.text | |
updateLabelVisibility() | |
proxyTextViewDelegate?.textViewDidChange?(textView) | |
} | |
@objc func startEditing() { | |
setupTextView() | |
floatingLabel.textColor = floatingLabelColor | |
textLabel.isHidden = true | |
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { | |
self.textView?.becomeFirstResponder() | |
} | |
} | |
func stopEditing() { | |
textView?.resignFirstResponder() | |
textView?.removeFromSuperview() | |
textView = nil | |
floatingLabel.textColor = UIColor.lightGray | |
textLabel.isHidden = false | |
} | |
private func updateLabelVisibility() { | |
let hideFloatingLabel = text?.count == 0 || text == nil | |
updateOpacity(hideFloatingLabel: hideFloatingLabel) | |
} | |
private func updateOpacity(hideFloatingLabel: Bool) { | |
floatingLabel.isHidden = hideFloatingLabel | |
hintLabel.isHidden = !hideFloatingLabel | |
} | |
private func setup() { | |
addTarget(self, action: #selector(startEditing), for: .touchUpInside) | |
setupFloatingLabel() | |
setupHintLabel() | |
setupTextLabel() | |
updateLabelVisibility() | |
} | |
private func setupTextView() { | |
let textView = UITextView(frame: CGRect.zero, textContainer: nil) | |
self.textView = textView | |
textView.translatesAutoresizingMaskIntoConstraints = false | |
textView.text = text | |
textView.isScrollEnabled = false | |
textView.font = UIFont.systemFont(ofSize: 17) | |
textView.backgroundColor = UIColor.clear | |
textView.delegate = self | |
textView.backgroundColor = UIColor.clear | |
textView.inputAccessoryView = proxyInputAccessoryView | |
addSubview(textView) | |
NSLayoutConstraint.activate([ | |
textView.leadingAnchor.constraint(equalTo: leadingAnchor), | |
textView.trailingAnchor.constraint(equalTo: textLabel.trailingAnchor), | |
textView.topAnchor.constraint(equalTo: floatingLabel.bottomAnchor, constant: -3.5) | |
]) | |
} | |
private func setupTextLabel() { | |
textLabel.translatesAutoresizingMaskIntoConstraints = false | |
textLabel.font = UIFont.systemFont(ofSize: 17) | |
textLabel.numberOfLines = 0 | |
addSubview(textLabel) | |
} | |
private func setupFloatingLabel() { | |
floatingLabel.translatesAutoresizingMaskIntoConstraints = false | |
floatingLabel.font = UIFont.systemFont(ofSize: 12) | |
floatingLabel.textColor = floatingLabelColor | |
addSubview(floatingLabel) | |
} | |
private func setupHintLabel() { | |
hintLabel.translatesAutoresizingMaskIntoConstraints = false | |
hintLabel.textColor = UIColor.lightGray | |
hintLabel.font = UIFont.systemFont(ofSize: 17) | |
addSubview(hintLabel) | |
} | |
private func setupConstraints() { | |
NSLayoutConstraint.activate([ | |
floatingLabel.topAnchor.constraint(equalTo: topAnchor, constant: 5), | |
floatingLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5), | |
textLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5), | |
textLabel.trailingAnchor.constraint(equalTo: trailingAnchor), | |
textLabel.topAnchor.constraint(equalTo: floatingLabel.bottomAnchor, constant: 5), | |
hintLabel.leadingAnchor.constraint(equalTo: textLabel.leadingAnchor), | |
hintLabel.topAnchor.constraint(equalTo: textLabel.topAnchor), | |
hintLabel.trailingAnchor.constraint(equalTo: textLabel.trailingAnchor), | |
bottomAnchor.constraint(greaterThanOrEqualTo: textLabel.bottomAnchor, constant: 5), | |
bottomAnchor.constraint(greaterThanOrEqualTo: hintLabel.bottomAnchor, constant: 5) | |
]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment