Reputation: 1
I have a subclass of UIView
in which I have UITextField
and wants to move placeholder text little right. I am using NSLayoutConstraint
for setting subviews position and size. I have created UIView
and adding it as leftView
of UITextField
but it crashes stating "The view hierarchy is not prepared for the constraint". Below is my code :
class MasterView: UIView {
let searchTextField = UITextField()
let paddingView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
searchTextField.placeholder = "Search videos"
searchTextField.translatesAutoresizingMaskIntoConstraints = false
paddingView.translatesAutoresizingMaskIntoConstraints = false
searchTextField.leftView = paddingView
searchTextField.leftViewMode = UITextFieldViewMode.Always
self.addSubview(searchTextField)
}
// Gets called when using storyboard
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
self.addConstraint(NSLayoutConstraint(item: searchTextField, attribute: NSLayoutAttribute.TopMargin, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.TopMargin, multiplier: 1.0, constant: 20))
self.addConstraint(NSLayoutConstraint(item: searchTextField, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.Height, multiplier: 0.12, constant: 0))
self.addConstraint(NSLayoutConstraint(item: searchTextField, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 0))
self.addConstraint(NSLayoutConstraint(item: searchTextField, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.Width, multiplier: 1.0, constant: 0))
self.addConstraint(NSLayoutConstraint(item: paddingView, attribute: NSLayoutAttribute.LeadingMargin, relatedBy: NSLayoutRelation.Equal, toItem: searchTextField, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 0))
self.addConstraint(NSLayoutConstraint(item: paddingView, attribute: NSLayoutAttribute.TopMargin, relatedBy: NSLayoutRelation.Equal, toItem: searchTextField, attribute: NSLayoutAttribute.TopMargin, multiplier: 1.0, constant: 0))
self.addConstraint(NSLayoutConstraint(item: paddingView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: searchTextField, attribute: NSLayoutAttribute.Width, multiplier: 0.12, constant: 0))
self.addConstraint(NSLayoutConstraint(item: paddingView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: searchTextField, attribute: NSLayoutAttribute.Height, multiplier: 1.0, constant: 0))
}
}
Upvotes: 0
Views: 8953
Reputation: 1039
Proper solution for this problem:
@IBDesignable
class FormTextField: UITextField {
@IBInspectable var paddingLeft: CGFloat = 0
@IBInspectable var paddingRight: CGFloat = 0
override func textRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(x: bounds.origin.x + paddingLeft, y: bounds.origin.y, width: bounds.size.width - paddingLeft - paddingRight, height: bounds.size.height)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return textRect(forBounds: bounds)
}
}
taken from here
Upvotes: 9
Reputation: 326
Make UITextField custom class and implement this two method in that class and make your textfield as custom textfield.
class customTextField: UITextField {
override func textRectForBounds(bounds: CGRect) -> CGRect {
return super.textRectForBounds(UIEdgeInsetsInsetRect(bounds, UIEdgeInsetsMake(0, 5, 0, 0)))
}
override func editingRectForBounds(bounds: CGRect) -> CGRect {
return super.editingRectForBounds(UIEdgeInsetsInsetRect(bounds, UIEdgeInsetsMake(0, 5, 0, 0)))
}
}
Upvotes: 4
Reputation: 8904
You are facing this error "The view hierarchy is not prepared for the constraint", because paddingView is added as left/right view and won't required any constraints.
Note : It is not required to give constraint to a view which is added as a left/right view to UITextField
. So you just need to set frame of a paddingView
and assign it to the leftView
. No need to give constraints to paddingView
.
Upvotes: 0
Reputation: 5299
Just write below:- SWIFT 2.1.1
let tempView = UIView(frame:CGRectMake(6, 0, 22, 26))
tempView.backgroundColor = UIColor.clearColor()
searchTextField.leftView?.frame = CGRectMake(0, 0, tempView.frame.size.width, tempView.frame.height)
searchTextField.leftViewMode = UITextFieldViewMode.Always
searchTextField.leftView = tempView
Upvotes: 0
Reputation: 27428
yon should not set or give constraints to that padding view. remove all constraints of padding view. it's left view of textfield
so it automatically adjust as per constraint of textfield. And set frame of padding view that what space you expect as padding.
Hope this will help :)
Upvotes: 0
Reputation:
Try this code it will help you
override func viewDidLoad() {
super.viewDidLoad()
let paddingView = UIView(frame: CGRectMake(0, 0, 15, self.myTextField.frame.height))
myTextField.leftView = paddingView
myTextField.leftViewMode = UITextFieldViewMode.Always
}
Upvotes: 0
Reputation: 3317
let paddingForFirst = UIView(frame: CGRectMake(0, 0, 5, self.Email_Txt.frame.size.height-5))
Email_Txt.leftView = paddingForFirst
Email_Txt.leftViewMode = UITextFieldViewMode .Always
Upvotes: 0