Skip to content

Instantly share code, notes, and snippets.

@laprasdrum
Last active March 28, 2018 09:13
Show Gist options
  • Save laprasdrum/5f860de4d0b0d0ebb662aec69c35055f to your computer and use it in GitHub Desktop.
Save laprasdrum/5f860de4d0b0d0ebb662aec69c35055f to your computer and use it in GitHub Desktop.
UITextField with shake error
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var label: UILabel!
enum Placeholder {
case normal, empty
var message: String {
switch self {
case .normal:
return "ここにテキストを入力"
case .empty:
return "1文字以上を入力しましょう"
}
}
}
var placeholderState = Placeholder.normal {
didSet {
textField.placeholder = placeholderState.message
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
textField.delegate = self
textField.returnKeyType = .send
NotificationCenter.default.addObserver(self, selector: #selector(changePlaceholderIfNeeded), name: NSNotification.Name.UITextFieldTextDidChange, object: textField)
}
@objc func changePlaceholderIfNeeded(_ notification: NSNotification) {
guard let field = notification.object as? UITextField else { return }
if field.text?.count ?? 0 > 0 {
placeholderState = .normal
}
}
}
extension ViewController {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField.text?.count == 0 {
placeholderState = .empty
textField.shake()
return false
} else {
textField.resignFirstResponder()
return true
}
}
func textFieldDidEndEditing(_ textField: UITextField) {
label.text = textField.text
}
}
public extension UIView {
// https://stackoverflow.com/a/38790163
func shake(count : Float = 4, for duration : TimeInterval = 0.2, withTranslation translation : CGFloat = 5) {
let animation : CABasicAnimation = CABasicAnimation(keyPath: "transform.translation.x")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.repeatCount = count
animation.duration = duration/TimeInterval(animation.repeatCount)
animation.autoreverses = true
animation.fromValue = NSValue(cgPoint: CGPoint(x: -translation, y: self.center.y))
animation.toValue = NSValue(cgPoint: CGPoint(x: translation, y: self.center.y))
layer.add(animation, forKey: "shake")
}
}
@laprasdrum
Copy link
Author

shake_textfield

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment