Reputation: 3769
I want to make this TextField
So I write this class
class UnderLineTextField:UITextField{
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.darkgray().cgColor
border.frame = CGRect(x: 0, y: frame.size.height - width, width: frame.size.width, height: frame.size.height)
textColor = UIColor.gold()
backgroundColor = UIColor.clear
border.borderWidth = width
layer.addSublayer(border)
layer.masksToBounds = true
attributedPlaceholder = NSAttributedString(string: "",
attributes: [NSAttributedStringKey.foregroundColor: UIColor.darkgray()])}
}
But there are two problems
The underline is not equal to TextField, if I add more width width: frame.size.width + 500
, the problem can be fixed, but why? what is the correct value I should pass to width:
?
attributedPlaceholder
will replace the placeholder I set in xib, how can I change placeholder without adding empty string?
Upvotes: 0
Views: 755
Reputation: 31
Hey already lot of answers :), let's see if this detailed answer can help you achieve more: I prefer using extensions over inheritance if possible.
extension UITextField {
func setTextColor(_ color: UIColor, font: UIFont) {
self.textColor = color
self.font = font
}
func setBottomBorder(with color: UIColor, width: CGFloat) {
self.borderStyle = .none
self.layer.backgroundColor = UIColor.white.cgColor // bg color of your choice
self.layer.masksToBounds = false
self.layer.shadowColor = color.cgColor
self.layer.shadowOffset = CGSize(width: 0.0, height: width)
self.layer.shadowOpacity = 1.0
self.layer.shadowRadius = 0.0
}
func setPlaceHolderAttributes(placeHolderText : String, colour : UIColor , font : UIFont){
self.attributedPlaceholder = NSAttributedString(string:placeHolderText, attributes:[NSAttributedStringKey.foregroundColor: colour , NSAttributedStringKey.font : font])
}
}
//MARK: To give text insets
class MyTextField: UITextField {
override func textRect(forBounds bounds: CGRect) -> CGRect {
return CGRect.init(x:10, y:2, width:bounds.width-20, height:bounds.height - 4)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return textRect(forBounds: bounds)
}
}
And I prefer to configure UI from Code, it will fasten up your coding speed and achieve doing project wise change from one place, so you can do it from code like:
let font: UIFont = UIFont.systemFont(ofSize: 14.0)
let placeHolderTextColor: UIColor = UIColor.brown
let textColor: UIColor = UIColor.darkText
nameTextField.setBottomBorder(with: UIColor.darkGray, width: 1.0)
passwordTextField.setBottomBorder(with: UIColor.darkGray, width: 1.0)
nameTextField.setPlaceHolderAttributes(placeHolderText: "Name", colour: placeHolderTextColor, font: font)
nameTextField.setTextColor(textColor, font: font)
passwordTextField.setPlaceHolderAttributes(placeHolderText: "Password", colour: placeHolderTextColor, font: font)
passwordTextField.setTextColor(textColor, font: font)
Hope this helps :)
Upvotes: 0
Reputation: 179
For UITextField
underline use this one...
let border = CALayer()
let width = CGFloat(1.0)
border.borderColor = UIColor.gray.cgColor
border.frame = CGRect(x: 0, y: textField.frame.size.height - width, width: textField.frame.size.width, height: textField.frame.size.height)
border.borderWidth = width
textField.layer.addSublayer(border)
textField.layer.masksToBounds = true
Upvotes: 0
Reputation: 2817
It seems your code is ok.
use below code for setting placeholder:
class UnderLineTextField:UITextField{
@IBInspectable var borderColor: UIColor = UIColor.white {
didSet {
layer.borderColor = borderColor.cgColor
}
}
@IBInspectable var placeHolderText: String = "default place holder" {
didSet {
attributedPlaceholder = NSAttributedString(string: placeHolderText,
attributes: [NSAttributedStringKey.foregroundColor: UIColor.darkGray])}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.darkGray.cgColor
border.frame = CGRect(x: 0, y: frame.size.height - width, width: frame.size.width, height: frame.size.height)
textColor = UIColor.lightGray
backgroundColor = UIColor.clear
border.borderWidth = width
layer.addSublayer(border)
layer.masksToBounds = true
attributedPlaceholder = NSAttributedString(string: placeHolderText,
attributes: [NSAttributedStringKey.foregroundColor: UIColor.darkGray])}
}
and set your placeholder in storyboard:
The result will look like below:
Upvotes: 1
Reputation: 3007
- The underline is not equal to TextField, if I add more width width: frame.size.width + 500, the problem can be fixed, but why? what is the correct value I should pass to width:?
You should put your draw underline code to draw(_ rect: CGRect)
instead of init
. Because of you using autolayout
, so the width, that you got in init
is difference with the width
that you can see when run app.
- attributedPlaceholder will replace the placeholder I set in xib, how can I change placeholder without adding empty string?
You can redraw the attributedPlaceholder base on your placeholder in draw(_ rect: CGRect)
, too
attributedPlaceholder = NSAttributedString(
string: self.placeholder,
attributes: [NSAttributedStringKey.foregroundColor: UIColor.darkgray()]
)
Upvotes: 1