Reputation: 5635
I am creating bottom bordered textfield. I am subclass of UITextField
. Here it is:
@IBDesignable class LinedTextField: UITextField {
@IBInspectable var borderColor: UIColor = UIColor.whiteColor() {
didSet {
let border = CALayer()
border.borderColor = self.borderColor.CGColor
border.frame = CGRect(x: 0, y: self.frame.size.height - borderWidth, width: self.frame.size.width, height: self.frame.size.height)
border.borderWidth = borderWidth
self.layer.addSublayer(border)
self.layer.masksToBounds = true
}
}
@IBInspectable var borderWidth: CGFloat = 0.5 {
didSet {
let border = CALayer()
border.borderColor = self.borderColor.CGColor
border.frame = CGRect(x: 0, y: self.frame.size.height - borderWidth, width: self.frame.size.width, height: self.frame.size.height)
border.borderWidth = borderWidth
self.layer.addSublayer(border)
self.layer.masksToBounds = true
}
}
override init(frame : CGRect) {
super.init(frame : frame)
setup()
}
convenience init() {
self.init(frame:CGRectZero)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override func awakeFromNib() {
super.awakeFromNib()
setup()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setup()
}
func setup() {
let border = CALayer()
border.borderColor = self.borderColor.CGColor
border.frame = CGRect(x: 0, y: self.frame.size.height - borderWidth, width: self.frame.size.width, height: self.frame.size.height)
border.borderWidth = borderWidth
self.layer.addSublayer(border)
self.layer.masksToBounds = true
}
override func layoutSubviews() {
super.layoutSubviews()
}
Then in interface builder I set that 2 properties(border colour and border width) and everything looks good:
But when I run application on my real 5.5" device, it looks this way:
Border is not long as the text field. What's wrong here?
Upvotes: 1
Views: 3716
Reputation: 2459
I think it's because the border frame need to be computed on layoutSubviews
. Here is an example on how to do so (plus a simplification of your code):
Supported in Swift 3
@IBDesignable class UnderlinedTextField: UITextField {
let border = CALayer()
@IBInspectable var borderColor: UIColor = UIColor.white {
didSet {
setup()
}
}
@IBInspectable var borderWidth: CGFloat = 0.5 {
didSet {
setup()
}
}
override init(frame : CGRect) {
super.init(frame : frame)
setup()
}
convenience init() {
self.init(frame:CGRect.zero)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override func awakeFromNib() {
super.awakeFromNib()
setup()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setup()
}
func setup() {
border.borderColor = self.borderColor.cgColor
border.borderWidth = borderWidth
self.layer.addSublayer(border)
self.layer.masksToBounds = true
}
override func layoutSubviews() {
super.layoutSubviews()
border.frame = CGRect(x: 0, y: self.frame.size.height - borderWidth, width: self.frame.size.width, height: self.frame.size.height)
}
override func textRect(forBounds bounds: CGRect) -> CGRect {
return editingRect(forBounds: bounds)
}
override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return editingRect(forBounds: bounds)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return bounds.insetBy(dx: 10, dy: 0)
}
}
EDIT:
I Added code for the text area. In this example, there is a 20px horizontal inset. There in more infos on editingRectForBounds
(and its friends) in the Apple's doc: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextField_Class/#//apple_ref/occ/instm/UITextField/textRectForBounds:
Upvotes: 3
Reputation: 3317
let border = CALayer()
border.borderColor = UIColor.blackColor().CGColor
border.frame = CGRectMake(-30, textField.frame.size.height - 1.0, textField.frame.size.width*1.5 , 1.0)
border.borderWidth = 1.0
textField.layer.addSublayer(border)
textField.layer.masksToBounds = true
Upvotes: 0
Reputation: 514
import UIKit
@IBDesignable
class MyTextField: UITextField {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
func setupView(){
self.borderStyle = UITextBorderStyle.None
let border = CALayer()
let borderWidth: CGFloat = 2
border.borderColor = UIColor(red: 5/255, green: 84/255, blue: 115/255, alpha: 1.0).CGColor
border.frame = CGRectMake(0, self.frame.size.height - borderWidth, self.frame.size.width, self.frame.size.height)
border.borderWidth = borderWidth
self.layer.addSublayer(border)
}
}
Upvotes: 0