Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save JayachandraA/603f2040b1ec1d38167e77d84c8fe8c0 to your computer and use it in GitHub Desktop.
Save JayachandraA/603f2040b1ec1d38167e77d84c8fe8c0 to your computer and use it in GitHub Desktop.

Revisions

  1. JayachandraA created this gist Sep 18, 2018.
    130 changes: 130 additions & 0 deletions How_to_create_a_stored_property_in_an_swift_extension.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@

    extension UITextField {

    // OPTION - 1
    struct Instance {
    static var floating: Bool = false
    }


    var floating: Bool{
    set{
    Instance.floating = newValue
    initializePlaceholder()
    }

    get{
    return Instance.floating
    }
    }



    // OPTION - 2
    struct AssociatedKeys {
    static var placeholderColor: String = "placeholderColor"
    }

    var placeholderColor: UIColor? {
    set {
    objc_setAssociatedObject(self, &AssociatedKeys.placeholderColor, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    updatePlaceholderAppearance()
    }

    get {
    guard let value = objc_getAssociatedObject(self, &AssociatedKeys.placeholderColor) as? UIColor else { return nil }
    return value
    }
    }


    // MARK: - Helper functions
    func initializePlaceholder(){
    guard floating == true else {
    return
    }
    if let _ = placeholderLabel(){
    return
    }

    addObserver(self, forKeyPath: "placeholder", options: NSKeyValueObservingOptions.new, context: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboard), name: NSNotification.Name.UIKeyboardWillHide, object: nil)


    let label = UILabel(frame: CGRect(origin: CGPoint(x: 5, y: 0), size: bounds.size))
    label.text = placeholder
    label.font = font
    addSubview(label)
    placeholder = ""
    let gesture = UITapGestureRecognizer(target: self, action: #selector(animatePlaceholderLabel))
    label.isUserInteractionEnabled = true
    label.tag = 765678
    label.addGestureRecognizer(gesture)
    }


    func placeholderLabel() ->UILabel? {
    if let label = viewWithTag(765678) as? UILabel{
    return label
    }
    return nil
    }

    fileprivate func fontSize() ->CGFloat? {
    return font?.pointSize
    }

    fileprivate func fontName() ->String? {
    return font?.familyName
    }

    fileprivate func updatePlaceholder() {
    guard let label = placeholderLabel() else { return }
    label.text = placeholder
    attributedPlaceholder = NSAttributedString(string: placeholder!, attributes: [NSAttributedStringKey.foregroundColor : UIColor.clear])
    }

    fileprivate func updatePlaceholderAppearance() {
    guard let label = placeholderLabel() else { return }
    label.font = self.font
    label.textColor = placeholderColor
    }


    @objc private func animatePlaceholderLabel() {
    becomeFirstResponder()
    guard let label = placeholderLabel() else { return }
    UIView.animate(withDuration: 0.5, animations: {
    label.frame = CGRect(origin: CGPoint(x: 5, y: -(self.bounds.size.height * 0.5 + 3)), size: CGSize(width: self.bounds.size.width * 0.5, height: self.bounds.size.height * 0.5))
    })
    }

    @objc func handleKeyboard() {
    if let count = text?.count, count > 0 { return }
    guard let label = placeholderLabel() else { return }
    UIView.animate(withDuration: 0.3, animations: {
    label.frame = CGRect(origin: CGPoint(x: 5, y: 0), size: self.bounds.size)
    if let name = self.fontName(), let size = self.fontSize(){
    label.font = UIFont(name: name, size: size)
    }
    })
    }



    open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if let path = keyPath, path == "placeholder" {
    updatePlaceholder()
    }
    }


    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
    // Drawing code
    }
    */

    }