Skip to content

Instantly share code, notes, and snippets.

@NeilsUltimateLab
Created November 12, 2019 16:13
Show Gist options
  • Save NeilsUltimateLab/44c80df3166bd8238f27d5782f693dc9 to your computer and use it in GitHub Desktop.
Save NeilsUltimateLab/44c80df3166bd8238f27d5782f693dc9 to your computer and use it in GitHub Desktop.
AutomaticSizing Message field to conversational screens.
class AppTextView: UITextView {
var onTextChange: ((String?)->Void)?
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
observeTextChanges()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
observeTextChanges()
}
private func observeTextChanges() {
NotificationCenter.default.addObserver(forName: UITextView.textDidChangeNotification, object: nil, queue: nil) { [weak self] (notification) in
guard let textView = notification.object as? UITextView, textView === self else { return }
self?.onTextChange?(textView.text)
}
}
override var canResignFirstResponder: Bool {
return true
}
}
import UIKit
class MessageFieldView: UIView {
@IBOutlet weak var textView: AppTextView!
@IBOutlet weak var sendButton: UIButton!
@IBOutlet weak var placeholderLabel: UILabel!
@IBOutlet weak var seperatorView: UIView!
var onSendAction: ((String)->Void)?
var onTextChange: (()->Void)?
override func awakeFromNib() {
super.awakeFromNib()
prepareUI()
observeTextChanges()
}
private func prepareUI() {
self.backgroundColor = UIColor.messageFieldColor
self.placeholderLabel.text = "Enter your message here..."
self.autoresizingMask = .flexibleHeight
self.textView.isScrollEnabled = false
self.textView.bounces = false
self.textView.textContainerInset = UIEdgeInsets(top: 6, left: 0, bottom: 6, right: 0)
self.seperatorView.backgroundColor = UIColor.shadowColor
}
private func observeTextChanges() {
self.textView.onTextChange = { [weak self] (text) in
self?.updatePlaceholderState()
self?.updateSelfHeight()
self?.onTextChange?()
}
}
override var intrinsicContentSize: CGSize {
var textSize = self.textView.sizeThatFits(CGSize(width: self.textView.bounds.width, height: CGFloat.greatestFiniteMagnitude))
if textSize.height >= 110 {
textSize.height = 110
self.textView.isScrollEnabled = true
self.textView.bounces = true
} else {
self.textView.setContentOffset(CGPoint.zero, animated: false)
self.textView.isScrollEnabled = false
self.textView.bounces = false
}
return CGSize(width: self.bounds.width, height: textSize.height)
}
private func updatePlaceholderState() {
self.layoutIfNeeded()
self.placeholderLabel.isHidden = !(textView.text.isEmpty)
}
private func updateSelfHeight() {
self.invalidateIntrinsicContentSize()
}
@IBAction func sendAction(_ sender: UIButton) {
guard let text = textView.text.validOptionalString else {
return
}
self.textView.isScrollEnabled = false
self.textView.text = ""
self.updateSelfHeight()
self.updatePlaceholderState()
self.onSendAction?(text)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment