Search This Blog

Tuesday, March 14, 2017

Create custom UITextField and custom clear button for it


Goals


  1. Create custom UITextField
    1. It should be transparent
    2. It should have border
    3. It should have rounded corners
    4. Rounded corners and border width should be setting via Xcode Interface Builder (IBInspectable / IBDesignable)
  2. Create custom clear button for custom UITextField
    1. Use Extensions for creating custom clear button
    2. Use Google Material Design Icon as image for button
    3. Set for button image custom color
    4. Make button always visible even if textfield is not in focus
    5. Set for button padding from right side of textfield
  3. Make textfield not editable but still available for touches
    1. Do not show keyboard
    2. Add default parameter values
    3. Clear button should be available for tap
    4. Fill textfield by clicking on special button
    5. Send Local Notification when custom clear button is tapped
  4. Use completely different approach for the same goal - Create custom clear button without adding Right View in UITextField

Implementation


Custom TextField

import UIKit
import UIKit

@IBDesignable
class CustomTextField: UITextField {
    
    @IBInspectable
    var borderWidth: CGFloat {
        get {
            return self.layer.borderWidth
        }
        set {
            self.layer.borderWidth = newValue
        }
    }
    
    @IBInspectable
    var borderColor: UIColor? {
        get {
            return UIColor(cgColor: self.layer.borderColor!)
        }
        set {
            self.layer.borderColor = newValue?.cgColor
        }
    }
    
    @IBInspectable
    var cornerRadius: CGFloat {
        set {
            self.layer.cornerRadius = newValue
        }
        get {
            return self.layer.cornerRadius
        }
    }

}






Add Custom Clear Button with Extensions


import Foundation
import UIKit

extension UITextField {
    
    func clearButtonWithImage(_ image: UIImage) {
        let clearButton = UIButton()
        clearButton.setImage(image, for: .normal)
        clearButton.frame = CGRect(x: 0, y: 0, width: 15, height: 15)
        clearButton.contentMode = .scaleAspectFit
        clearButton.addTarget(self, action: #selector(self.clear(sender:)), for: .touchUpInside)
        self.rightView = clearButton
        self.rightViewMode = .always
    }
    
    func clear(sender: AnyObject) {
        self.text = ""
    }
    
}

override func viewDidLoad() {
        super.viewDidLoad()
        
        let clearImage = UIImage(named: "ic_close_white_48pt")!
        self.firstWordTextField.clearButtonWithImage(clearImage)
}





Moving Clear Button

override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
        var rightViewRect = super.rightViewRect(forBounds: bounds)
        rightViewRect.origin.x -= 10;
        return rightViewRect
}

import UIKit
import UIKit

@IBDesignable
class CustomTextField: UITextField {
    
    @IBInspectable
    var borderWidth: CGFloat {
        get {
            return self.layer.borderWidth
        }
        set {
            self.layer.borderWidth = newValue
        }
    }
    
    @IBInspectable
    var borderColor: UIColor? {
        get {
            return UIColor(cgColor: self.layer.borderColor!)
        }
        set {
            self.layer.borderColor = newValue?.cgColor
        }
    }
    
    @IBInspectable
    var cornerRadius: CGFloat {
        set {
            self.layer.cornerRadius = newValue
        }
        get {
            return self.layer.cornerRadius
        }
    }
    
    override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
        var rightViewRect = super.rightViewRect(forBounds: bounds)
        rightViewRect.origin.x -= 10;
        return rightViewRect
    }

}





Add Color to Clear Button

import Foundation
import UIKit

extension UITextField {
    
    func clearButtonWithImage(_ image: UIImage,
                              _ imageColor: UIColor = UIColor.white,
                              _ isAlwaysVisible: Bool = true) {
        let clearButton = UIButton()
        clearButton.tintColor = imageColor
        let coloredImage = image.withRenderingMode(.alwaysTemplate)
        clearButton.setImage(coloredImage, for: .normal)
        clearButton.frame = CGRect(x: 0, y: 0, width: 15, height: 15)
        clearButton.contentMode = .scaleAspectFit
        clearButton.addTarget(self, action: #selector(self.clear(sender:)), for: .touchUpInside)
        self.rightView = clearButton
        self.rightViewMode = isAlwaysVisible ? .always : .never
    }
    
    func clear(sender: AnyObject) {
        self.text = ""
    }
    
}


Create two clear buttons with default color and with custom color

override func viewDidLoad() {
        super.viewDidLoad()
        
        let clearImage = UIImage(named: "ic_close_white_48pt")!
        
        self.firstWordTextField.clearButtonWithImage(clearImage)
        self.secondWordTextField.clearButtonWithImage(clearImage, UIColor.red)
}




Send Local Notification when tapped on clear button

import Foundation
import UIKit

extension UITextField {
    
    func clearButtonWithImage(_ image: UIImage,
                              _ imageColor: UIColor = UIColor.white,
                              _ isAlwaysVisible: Bool = true) {
        let clearButton = UIButton()
        clearButton.tintColor = imageColor
        let coloredImage = image.withRenderingMode(.alwaysTemplate)
        clearButton.setImage(coloredImage, for: .normal)
        clearButton.frame = CGRect(x: 0, y: 0, width: 15, height: 15)
        clearButton.contentMode = .scaleAspectFit
        clearButton.addTarget(self, action: #selector(self.clear(sender:)), for: .touchUpInside)
        self.rightView = clearButton
        self.rightViewMode = isAlwaysVisible ? .always : .never
    }
    
    func clear(sender: AnyObject) {
        self.text = ""
        
        NotificationCenter.default.post(
            name: Notification.Name("TextFieldCleared"), object: nil, userInfo: nil)
    }
    
}

override func viewDidLoad() {
        super.viewDidLoad()
        
        let clearImage = UIImage(named: "ic_close_white_48pt")!
        
        self.firstWordTextField.clearButtonWithImage(clearImage)
        self.secondWordTextField.clearButtonWithImage(clearImage, UIColor.red)
        
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(ViewController.clearSelection),
                                               name: Notification.Name("TextFieldCleared"),
                                               object: nil)
}




Full Code of ViewController

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var firstWordTextField: CustomTextField!
    
    @IBOutlet weak var secondWordTextField: CustomTextField!
    
    @IBOutlet weak var firstButton: UIButton!
    
    @IBOutlet weak var secondButton: UIButton!
    
    var isFirstSelected: Bool = false
    
    var isSecondSelected: Bool = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let clearImage = UIImage(named: "ic_close_white_48pt")!
        
        self.firstWordTextField.clearButtonWithImage(clearImage)
        self.secondWordTextField.clearButtonWithImage(clearImage, UIColor.red)
        
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(ViewController.clearSelection),
                                               name: Notification.Name("TextFieldCleared"),
                                               object: nil)
    }
    
    @IBAction func firstButtonTapped(_ sender: Any) {
        if !self.isFirstSelected {
            self.firstWordTextField.text = "Fill First TextField"
            self.setFirstButtonSelected(selected: !self.firstButton.isSelected)
        }
    }
    
    @IBAction func secondButtonTapped(_ sender: Any) {
        if !self.isSecondSelected {
            self.secondWordTextField.text = "A long time ago"
            self.setSecondButtonSelected(selected: !self.secondButton.isSelected)
        }
    }
    
    
    func clearSelection() {
        if self.isFirstSelected {
            if let text = self.firstWordTextField.text {
                if text.isEmpty {
                    self.setFirstButtonSelected(selected: false)
                }
            }
        }
        
        if self.isSecondSelected {
            if let text = self.secondWordTextField.text {
                if text.isEmpty {
                    self.setSecondButtonSelected(selected: false)
                }
            }
        }
    }
    
    func setFirstButtonSelected(selected: Bool) {
        self.isFirstSelected = selected
        self.firstButton.isSelected = selected
    }
    
    func setSecondButtonSelected(selected: Bool) {
        self.isSecondSelected = selected
        self.secondButton.isSelected = selected
    }

}


Sources




6 comments:

  1. There are many articles circulating on internet that exaggerate about Custom Website. But your article is an exception that made me understand it without any difficulty.

    ReplyDelete
  2. You've written a fascinating piece of writing. This is exactly the kind of information I was looking for. Please provide me with more relevant information so that I can learn more. Best Custom Websites

    ReplyDelete
  3. Thank you very much for drawing my notice to this. Your blog is jam-packed with useful facts. Until I read that, I would have no idea. I'll come back for more fantastic material.
    Best wishes, and good luck.
    Web Design USA

    ReplyDelete
  4. Good content. I was looking for this type of content. Saved my time for further search.
    You should always provide that type of content. I appreciate your determination to give the students a good title.Custom Designed Websites

    ReplyDelete
  5. Amazing write-up! The blog was very informative. Keep it up!
    Custom Web Developer

    ReplyDelete