Nirmal
Nirmal

Reputation: 1

How to add padding inside UITextField using NSLayoutConstraint in Swift?

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

Answers (7)

Giggs
Giggs

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

riddhi
riddhi

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

Mahendra
Mahendra

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

Mitul Marsoniya
Mitul Marsoniya

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

Ketan Parmar
Ketan Parmar

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

user5938635
user5938635

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

Jayesh Miruliya
Jayesh Miruliya

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

Related Questions