So, I have this custom UITextField
and I have two methods to add CALayer
and remove the CALayer
but remove is not working.
@IBDesignable class AppTextField : UITextField {
private let bottomLine = CALayer()
override func layoutSubviews() {
self.font = .systemFont(ofSize: 20)
self.addBottomLine()
self.clearButtonMode = .unlessEditing
super.layoutSubviews()
}
func removeBttomLine() {
bottomLine.removeFromSuperlayer()
}
private func addBottomLine() {
bottomLine.frame = CGRect(origin: CGPoint(x: 0, y: self.frame.height + 4), size: CGSize(width: self.frame.width, height: 1))
bottomLine.backgroundColor = UIColor.init(hexString: "#DCCFCA")?.cgColor
self.borderStyle = .none
self.layer.addSublayer(bottomLine)
}
}
The only thing you should do in layoutSubviews()
is update frames as necessary.
This will show the red line when the field is NOT being edited, and will remove it while the field IS being edited:
@IBDesignable class AppTextField : UITextField {
private let bottomLine = CALayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
self.font = .systemFont(ofSize: 20)
self.backgroundColor = .white
self.clearButtonMode = .unlessEditing
self.borderStyle = .none
bottomLine.backgroundColor = UIColor.red.cgColor
addBottomLine()
}
override func layoutSubviews() {
super.layoutSubviews()
var r = bounds
r.origin.y = bounds.maxY
r.size.height = 4.0
bottomLine.frame = r
}
func removeBottomLine() {
bottomLine.removeFromSuperlayer()
}
private func addBottomLine() {
self.layer.addSublayer(bottomLine)
}
override func resignFirstResponder() -> Bool {
super.resignFirstResponder()
addBottomLine()
return true
}
override func becomeFirstResponder() -> Bool {
super.becomeFirstResponder()
removeBottomLine()
return true
}
}