How do I add padding to a UITextField with an icon
Solution 1
"Update: Thanks for the replies. I achieved this in the end by creating a UIView for the entire object with a UIImageView for the icon and a UITextField embedded in another UIView for the text."
You could have continued using the leftView
property of the UITextField
such:
UIView *vwContainer = [[UIView alloc] init];
[vwContainer setFrame:CGRectMake(0.0f, 0.0f, 50.0f, 45.0f)];
[vwContainer setBackgroundColor:[UIColor clearColor]];
UIImageView *icon = [[UIImageView alloc] init];
[icon setImage:[UIImage imageNamed:@"text-input-icon-password-key.png"]];
[icon setFrame:CGRectMake(0.0f, 0.0f, 45.0f, 45.0f)];
[icon setBackgroundColor:[UIColor lightGrayColor]];
[vwContainer addSubview:icon];
[self.passwordTextField setLeftView:vwContainer];
[self.passwordTextField setLeftViewMode:UITextFieldViewModeAlways];
Solution 2
If you want full control over the custom layout then you should subclass UITextField
and override both the leftViewRectForBounds:
and placeholderRectForBounds:
methods. Then you can return the frames for both areas and thus specify the padding in between them.
Solution 3
Here is a UITextField subclass that allows for insets on the leftView (icon), the text and the placeholder text. These are all configurable in IB
class UITextFieldWithInsets: UITextField {
@IBInspectable var horizontalInset:CGFloat = 0
@IBInspectable var verticalInset:CGFloat = 0
@IBInspectable var leftViewHorizontalInset:CGFloat = 0
@IBInspectable var leftViewVerticalInset:CGFloat = 0
override func textRectForBounds(bounds: CGRect) -> CGRect {
return CGRectInset(bounds , horizontalInset , verticalInset)
}
override func editingRectForBounds(bounds: CGRect) -> CGRect {
return CGRectInset(bounds , horizontalInset + leftViewHorizontalInset + leftViewWidth, verticalInset)
}
override func placeholderRectForBounds(bounds: CGRect) -> CGRect {
return CGRectInset(bounds, horizontalInset + leftViewHorizontalInset + leftViewWidth, verticalInset)
}
override func leftViewRectForBounds(bounds: CGRect) -> CGRect {
let verticalInsetForCentered = (bounds.height - leftViewHeight) / 2
return CGRect(x: leftViewHorizontalInset, y: leftViewVerticalInset > 0 ? leftViewVerticalInset : verticalInsetForCentered, width: leftViewWidth, height: leftViewHeight)
}
private var leftViewWidth : CGFloat { get { return leftView?.frame.width ?? 0 } }
private var leftViewHeight : CGFloat { get { return leftView?.frame.width ?? 0 } }
}
Steve Walsh
Head of Software, Nixplay website You can see more about me here
Updated on June 04, 2022Comments
-
Steve Walsh almost 2 years
I currently have the following code to setup a password textfield:
self.passwordTextField = [UITextField new]; self.passwordTextField.placeholder = @"Password"; self.passwordTextField.font = [UIFont systemFontOfSize:18.f]; self.passwordTextField.secureTextEntry = YES; self.passwordTextField.returnKeyType = UIReturnKeyDone; self.passwordTextField.delegate = self; self.passwordTextField.backgroundColor = [UIColor colorWithRed:255 green:255 blue:255 alpha:0.64]; self.passwordTextField.layer.borderColor = [[UIColor lightGrayColor] CGColor]; self.passwordTextField.layer.borderWidth = 1.0f; CGFloat textFieldHeight = 45.f; CGFloat textFieldWidth = 300.f; self.passwordTextField.frame = CGRectMake(DIALOG_VIEW_WIDTH/2.f - textFieldWidth / 2.f, 240.f, textFieldWidth, textFieldHeight); UIImageView *icon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"text-input-icon-password-key.png"]]; icon.frame = CGRectMake(0, 0, 45.f, 45.f); icon.backgroundColor = [UIColor lightGrayColor]; self.passwordTextField.leftView = icon; self.passwordTextField.leftViewMode = UITextFieldViewModeAlways; [self.dialogView addSubview:self.passwordTextField];
which gives me this:
However, I want to add some more transparent padding to the left of the placeholder text and to the right of the image view showing the icon. Any ideas how this can be done?
Update: Thanks for the replies. I achieved this in the end by creating a UIView for the entire object with a UIImageView for the icon and a UITextField embedded in another UIView for the text. The result was as follows:
-
Steve Walsh about 10 yearsIs there a way to do this without overriding UITextField?
-
Jano almost 7 yearsReader beware: with this solution the inset is applied on both sides decreasing the editing area. This can be corrected, for example, for editingRect, let the body be let xMargin = horizontalInset + leftViewHorizontalInset + leftViewWidth; return CGRect(x: xMargin, y: bounds.origin.y, width: bounds.size.width - xMargin, height: bounds.size.height)