Skip to content

Instantly share code, notes, and snippets.

@spencerwhyte
Created October 3, 2018 23:55
Show Gist options
  • Save spencerwhyte/56682b42f53850c3216da6cb1f206010 to your computer and use it in GitHub Desktop.
Save spencerwhyte/56682b42f53850c3216da6cb1f206010 to your computer and use it in GitHub Desktop.
Beginnings of a floating label text view
//
// FloatingTextView.swift
// DocumentsUI
//
// Created by Spencer Whyte on 2018-10-03.
// Copyright © 2018 Probuild Software Inc. All rights reserved.
//
import UIKit
class FloatingTextView: UITextView {
var label: String? {
didSet {
floatingLabel.text = label
hintLabel.text = label
}
}
var floatingLabelColor: UIColor = UIColor.lightGray
private let floatingLabelPadding: CGFloat = 20
private let floatingLabel: UILabel
private let hintLabel: UILabel
private var lastHideFloatingLabel: Bool? = nil
init() {
floatingLabel = UILabel()
hintLabel = UILabel()
let startDate = Date()
super.init(frame: CGRect.zero, textContainer: nil)
print(Date().timeIntervalSince(startDate))
textContainerInset = UIEdgeInsets(top: 17, left: textContainerInset.left, bottom: textContainerInset.bottom, right: textContainerInset.right)
setup()
setupConstraints()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var text: String! {
didSet {
updateLabelVisibility(shouldAnimate: false)
}
}
@objc func textDidChange() {
updateLabelVisibility(shouldAnimate: true)
}
@objc func didBeginEditing() {
self.floatingLabel.textColor = floatingLabelColor
}
@objc func didEndEditing() {
self.floatingLabel.textColor = UIColor.lightGray
}
private func updateLabelVisibility(shouldAnimate: Bool) {
let hideFloatingLabel = self.text.count == 0
if shouldAnimate {
if hideFloatingLabel != lastHideFloatingLabel {
lastHideFloatingLabel = hideFloatingLabel
UIView.animate(withDuration: 0.5, delay: 0, options: [UIView.AnimationOptions.curveEaseOut, UIView.AnimationOptions.beginFromCurrentState], animations: {
self.updateOpacity(hideFloatingLabel: hideFloatingLabel)
}, completion: nil)
}
} else {
updateOpacity(hideFloatingLabel: hideFloatingLabel)
}
}
private func updateOpacity(hideFloatingLabel: Bool) {
let floatingLabelOpacity: CGFloat = hideFloatingLabel ? 0 : 1
let hintLabelOpacity: CGFloat = hideFloatingLabel ? 1 : 0
self.floatingLabel.alpha = floatingLabelOpacity
self.hintLabel.alpha = hintLabelOpacity
}
private func setup() {
isScrollEnabled = false
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange), name:UITextView.textDidChangeNotification, object: self)
NotificationCenter.default.addObserver(self, selector: #selector(didBeginEditing), name:UITextView.textDidBeginEditingNotification, object: self)
NotificationCenter.default.addObserver(self, selector: #selector(didEndEditing), name:UITextView.textDidEndEditingNotification, object: self)
setupFloatingLabel()
setupHintLabel()
updateLabelVisibility(shouldAnimate: false)
}
private func setupFloatingLabel() {
floatingLabel.translatesAutoresizingMaskIntoConstraints = false
floatingLabel.font = UIFont.systemFont(ofSize: 8)
floatingLabel.textColor = floatingLabelColor
addSubview(floatingLabel)
}
private func setupHintLabel() {
hintLabel.translatesAutoresizingMaskIntoConstraints = false
hintLabel.textColor = UIColor.lightGray
hintLabel.font = UIFont.systemFont(ofSize: 11)
addSubview(hintLabel)
}
private func setupConstraints() {
NSLayoutConstraint.activate([
floatingLabel.topAnchor.constraint(equalTo: topAnchor, constant: 5),
floatingLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5),
hintLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5),
hintLabel.topAnchor.constraint(equalTo: floatingLabel.bottomAnchor, constant: 3),
bottomAnchor.constraint(greaterThanOrEqualTo: hintLabel.bottomAnchor),
heightAnchor.constraint(greaterThanOrEqualToConstant: 50)
])
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment