Goals
- Create custom UITextField
- It should be transparent
- It should have border
- It should have rounded corners
- Rounded corners and border width should be setting via Xcode Interface Builder (IBInspectable / IBDesignable)
- Create custom clear button for custom UITextField
- Use Extensions for creating custom clear button
- Use Google Material Design Icon as image for button
- Set for button image custom color
- Make button always visible even if textfield is not in focus
- Set for button padding from right side of textfield
- Make textfield not editable but still available for touches
- Do not show keyboard
- Add default parameter values
- Clear button should be available for tap
- Fill textfield by clicking on special button
- Send Local Notification when custom clear button is tapped
- 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