408

I wanted to use a custom background for my UITextFields. This works fine except for the fact that I have to use UITextBorderStyleNone to make it look pretty. This forces the text to stick to the left without any padding.

Can I set a padding manually so that it looks similar to UITextBorderStyleRoundedRect except for using my custom background image?

shim
  • 7,170
  • 10
  • 62
  • 95
Sebastian Wramba
  • 9,837
  • 8
  • 36
  • 56

32 Answers32

859

I found a neat little hack to set the left padding for this exact situation.

Basically, you set the leftView property of the UITextField to be an empty view of the size of the padding you want:

UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
textField.leftView = paddingView;
textField.leftViewMode = UITextFieldViewModeAlways;

Worked like a charm for me!

In Swift 3/ Swift 4, it can be done by doing that

let paddingView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 5, height: 20))
textField.leftView = paddingView
textField.leftViewMode = .always
dahiya_boy
  • 7,885
  • 1
  • 25
  • 39
Evil Trout
  • 9,453
  • 2
  • 19
  • 17
  • 1
    Exactly what I needed, except I needed padding to the right which is mostly the same, of course. Thanks! – cg. Mar 24 '11 at 15:30
  • @Lukasz I added an autorelease to this answer, the accepted answer. First line. EDIT: oops, maybe I didn't save? or my edit was rejected? Either way, Vincent added in an autorelease, so yay for that! – Eric Goldberg Aug 12 '11 at 22:12
  • This works great but when i am using same View for multiple UITextfield then it's not working showing me white page.Is the same happend with you too? – Sandy Jun 11 '13 at 07:05
  • 1
    Using ARC, why does my app hang and use a lot of CPU if I reuse `*paddingView` with multiple text fields? – The Muffin Man Nov 27 '13 at 17:03
  • 3
    It's a bad solution, better go for Nate Flink's one. Thios one doesn't include editiong mode padding. – Jacek Kwiecień Dec 02 '13 at 08:29
  • I did create a custom method by using this Trick and have added an answer in this thread! This perfectly works on iOS 7! Thanks Evil Trout!!! (Y) Following is the Answer: http://stackoverflow.com/a/22471157/1752988 – Randika Vishman Mar 18 '14 at 05:34
  • 3
    It is not working with multiple textfields. Just consumes so much memory and later crashes. – birdcage Apr 25 '14 at 14:50
  • @gbesler try to release the view and again alocate the memory of view and then asing it to different text field. It will work. I had same issue and I solved it with this. – BSKANIA Jul 30 '14 at 06:45
  • Not sure if anyone else experienced this, but the subviews added do not respond to touches/taps, so if the user taps on the area where the `UIView` resides the textfield does not become `firstResponder`. In order to get around this issue, a possible fix can be to add a gesture recognizer to the view with `becomeFirstResponder` as the selector. – Julian B. Aug 26 '14 at 19:45
  • @coco yes, i am having this issue but why so?? i ended up subclassing UITextField, & it worked. – maddy Nov 24 '14 at 15:13
  • @Alok I assume it's because a single UIView cannot be placed in two different spots at the same time. (Strange coincidence: I ran into this same problem again tonight! I'm so glad you reminded me..) – coco Nov 25 '14 at 02:12
  • Yes, this is kind of hack but when used in certain way works good and when that padding is just small it is not problem that it consume clicks... – Renetik Aug 27 '15 at 10:26
  • Can some one look at the similar problem but the padding is on the right side. I do not want to mess up with leftview and right view, as I need it for some other purpose. – IronMan Oct 09 '16 at 19:48
  • 2
    why this is accepted and has 700+ ups? It doesn't add padding to left. For example, what if I already use textfield's leftView for something? – Zaporozhchenko Oleksandr Jun 01 '17 at 17:59
180

I created this category implementation and added it to the top of the .m file.

@implementation UITextField (custom)
    - (CGRect)textRectForBounds:(CGRect)bounds {
        return CGRectMake(bounds.origin.x + 10, bounds.origin.y + 8,
                          bounds.size.width - 20, bounds.size.height - 16);
    }
    - (CGRect)editingRectForBounds:(CGRect)bounds {
        return [self textRectForBounds:bounds];
    }
@end

Based off the link Piotr Blasiak provided. It seemed simpler then creating a whole new subclass, and also simpler then adding the additional UIView. Still, it seems like something is missing to not be able to control the padding inside a text field.

Swift 4 solution:

class CustomTextField: UITextField {
    struct Constants {
        static let sidePadding: CGFloat = 10
        static let topPadding: CGFloat = 8
    }

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(
            x: bounds.origin.x + Constants.sidePadding,
            y: bounds.origin.y + Constants.topPadding,
            width: bounds.size.width - Constants.sidePadding * 2,
            height: bounds.size.height - Constants.topPadding * 2
        )
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return self.textRect(forBounds: bounds)
    }
}
nickromano
  • 825
  • 8
  • 15
Nate Flink
  • 3,764
  • 2
  • 27
  • 18
  • 6
    This throws warnings about categories overriding methods. See [this answer](http://stackoverflow.com/a/9622779/659989) to suppress them. – pdenya Jun 07 '12 at 17:35
  • 5
    I prefer not doing this in a category, but other than that this is a cleaner solution than the accepted answer. – Bob Vork Dec 04 '12 at 13:46
  • 2
    It's better to use CGRectInset() for something like this, instead of rolling your own. It's a little cleaner looking as well: return CGRectInset(bounds, 10, 8); – Dennis Munsie May 14 '14 at 18:31
  • @EgeAkpinar but what if we want different padding in all four sides ..? Can we use `CGRectInset` in this case ..? – shashwat Jun 12 '14 at 11:11
  • 1
    @shashwat yes, you can specify any padding you'd want – Ege Akpinar Jun 13 '14 at 12:49
  • 1
    When I added this 4 years ago, things were different with iOS, and I agree that now it is best to create a subclass. However, if you just want a fast and dirty way to visually inspect your pixel distances, this will do it ;) So its ok for people keep voting!! – Nate Flink May 11 '15 at 19:06
141

A Swift 3 version for Xcode >6, where you can edit the inset value in Interface Builder / Storyboard.

import UIKit

@IBDesignable
class FormTextField: UITextField {

    @IBInspectable var inset: CGFloat = 0

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: inset, dy: inset)
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return textRect(forBounds: bounds)
    }

}

enter image description here

bandejapaisa
  • 24,838
  • 13
  • 86
  • 110
  • 1
    I don't see the form text field on mine. – okysabeni Mar 26 '15 at 00:20
  • 2
    I needed to add this line `override func placeholderRectForBounds(bounds: CGRect) -> CGRect { return CGRectInset(bounds, inset, inset) }` – Michael Apr 30 '15 at 19:15
  • 2
    This answer would be more helpful with an explanation or link to explanation of what `@IBDesignable` and `@IBInspectable` do, [i.e. this post at nshipster](http://nshipster.com/ibinspectable-ibdesignable/) – Russell Austin May 19 '15 at 04:53
  • 2
    If you are relying on any accessory views (such as the clear button functionality on UITextField) then `return super.textRectForBounds(CGRectInset(bounds, inset, inset))` will handle the offset from the accessory views properly. – Mike Fay Jun 25 '15 at 17:07
  • @okysabeni you need to click on your textfield and change the Class to FormTextField – Gustavo Barbosa Jan 30 '17 at 18:34
  • Swift 3 > Go to "Show Identity Inspector" Add your "Custom Class". In this example. Add "FormTextField" in Custom Class. – Fran Ceriu Apr 27 '17 at 02:12
  • This should be the selected answer, because it does not cause the text to jump around when editing starts like the accepted answer does. – xaphod Apr 03 '19 at 06:20
78

Edit: Still works in iOS 11.3.1

In iOS 6 myTextField.leftView = paddingView; is causing issue

This solves the problem

myTextField.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0)

For right aligned text field use CATransform3DMakeTranslation(-5, 0, 0) as mention by latenitecoder in comments

Inder Kumar Rathore
  • 37,431
  • 14
  • 121
  • 176
  • 1
    Nice, I had to put the padding in all textfields of the app, I created a category of UITextField and put this code inside -(void)awakeFromNib{} and this solved my problem – Teena nath Paul Jan 18 '15 at 12:51
  • So simple! Thx :) I have a question how can I make a simple code to make all UITextField instead of writing the code many time? – Luai Kalkatawi Feb 10 '15 at 15:25
  • Yeah I have read that comment but couldn't know how and where to write it. @InderKumarRathore – Luai Kalkatawi Feb 11 '15 at 06:11
  • 1
    All the other comments assume you want to pad a UITextField from the left. Subclassing is a lot of overhead to add some spacing id rather just add some blank characters but this solution is THE solution. One line future proof. If you are working with a textfield that is text right aligned use minus value (-5,0,0) Thanks Inder – latenitecoder Apr 09 '15 at 15:23
  • This has recently stopped working for me, looks fine in simulator but on device the text and placeholders are not visible and in fact appear hidden in the center of the screen (double tapping to paste shows pointer there) – Chris Edwards Apr 13 '15 at 16:31
  • 1
    After 4yrs I found my own answer :D , @latenitecoder your comment was what is needed. Updating the answer – Inder Kumar Rathore May 05 '18 at 09:26
  • 1
    what can i do if i want both right and left padding ?? – Mina Gerges Aug 19 '19 at 13:12
70

A good approach to add padding to UITextField is to subclass and add an edgeInsets property. You then set the edgeInsets and the UITextField will be drawn accordingly. This will also function correctly with a custom leftView or rightView set.

OSTextField.h

#import <UIKit/UIKit.h>

@interface OSTextField : UITextField

@property (nonatomic, assign) UIEdgeInsets edgeInsets;

@end

OSTextField.m

#import "OSTextField.h"

@implementation OSTextField

- (id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.edgeInsets = UIEdgeInsetsZero;
    }
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if(self){
        self.edgeInsets = UIEdgeInsetsZero;
    }
    return self;
}

- (CGRect)textRectForBounds:(CGRect)bounds {
    return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [super editingRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}

@end
Brody Robertson
  • 8,107
  • 2
  • 40
  • 42
25

Just subclass UITextField like this:

@implementation DFTextField


- (CGRect)textRectForBounds:(CGRect)bounds
{
    return CGRectInset(bounds, 10.0f, 0);
}

- (CGRect)editingRectForBounds:(CGRect)bounds
{
    return [self textRectForBounds:bounds];
}


@end

This adds horizontal padding of 10 points either side.

Camsoft
  • 10,713
  • 18
  • 78
  • 119
21

Objective C Code

MyTextField.h

#import <UIKit/UIKit.h>

@interface MyTextField : UITextField

@property (nonatomic) IBInspectable CGFloat padding;

@end

MyTextField.m

#import "MyTextField.h"

IB_DESIGNABLE
@implementation MyTextField

@synthesize padding;

-(CGRect)textRectForBounds:(CGRect)bounds{
    return CGRectInset(bounds, padding, padding);
}

-(CGRect)editingRectForBounds:(CGRect)bounds{
    return [self textRectForBounds:bounds];
}

@end

enter image description here

Kirit Vaghela
  • 12,245
  • 4
  • 72
  • 79
21
  1. Create a textfield Custom

PaddingTextField.swift

import UIKit
class PaddingTextField: UITextField {

@IBInspectable var paddingLeft: CGFloat = 0
@IBInspectable var paddingRight: CGFloat = 0

override func textRectForBounds(bounds: CGRect) -> CGRect {
    return CGRectMake(bounds.origin.x + paddingLeft, bounds.origin.y,
        bounds.size.width - paddingLeft - paddingRight, bounds.size.height);
}

override func editingRectForBounds(bounds: CGRect) -> CGRect {
    return textRectForBounds(bounds)
}}
  1. Set your textfield class is PaddingTextField and custom your padding as you want enter image description here enter image description here

  2. Enjoy it

final

777Q
  • 369
  • 3
  • 5
18

Based on Evil Trout's answer you might wanna create a category to make it easier to use across multiple applications.

Header file:

@interface UITextField (PaddingText)

-(void) setLeftPadding:(int) paddingValue;

-(void) setRightPadding:(int) paddingValue;
@end

Implementation file:

#import "UITextField+PaddingText.h"

@implementation UITextField (PaddingText)

-(void) setLeftPadding:(int) paddingValue
{
    UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, paddingValue, self.frame.size.height)];
    self.leftView = paddingView;
    self.leftViewMode = UITextFieldViewModeAlways;
}

-(void) setRightPadding:(int) paddingValue
{
    UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, paddingValue, self.frame.size.height)];
    self.rightView = paddingView;
    self.rightViewMode = UITextFieldViewModeAlways;
}

@end

Usage Example

#import "UITextField+PaddingText.h"

[self.YourTextField setLeftPadding:20.0f];

Hope it helps you out guys

Cheers

Paulo Miguel Almeida
  • 2,064
  • 29
  • 34
15

Swift version:

extension UITextField {
    @IBInspectable var padding_left: CGFloat {
        get {
            LF.log("WARNING no getter for UITextField.padding_left")
            return 0
        }
        set (f) {
            layer.sublayerTransform = CATransform3DMakeTranslation(f, 0, 0)
        }
    }
}

So that you can assign value in IB

IBInspectable setting represented in Interface Builder

Sebastian Wramba
  • 9,837
  • 8
  • 36
  • 56
superarts.org
  • 6,508
  • 1
  • 53
  • 43
  • `IBInspectable` allows you to apply the setter code at runtime, so simply put your number in `Interface Builder` and it will work. – superarts.org Dec 20 '16 at 22:29
  • This will not work when you have `Clear Button`. Your clear button will not visible if apply this solution. – Bhavin_m Jul 31 '18 at 09:46
12

You can't set padding. Instead have a UIView which has your background image and the UITextField inside of it. Set the UITextField width as UIViewWidth-(paddingSize x 2) and the height similarly and then set it at point paddingSize,paddingSize.

Paras Joshi
  • 19,954
  • 11
  • 54
  • 69
Thomas Clayson
  • 28,448
  • 25
  • 135
  • 216
10

Just subclass UITextField like this (Swift version):

import UIKit

class CustomTextField: UITextField {

    override func textRectForBounds(bounds: CGRect) -> CGRect {
       return CGRectInset(bounds, 25.0, 0)
    }

    override func editingRectForBounds(bounds: CGRect) -> CGRect {
       return self.textRectForBounds(bounds)
    }

}

This adds horizontal padding of 25.0 points either side.

King-Wizard
  • 14,974
  • 4
  • 79
  • 74
8

I was based off Nate's solution, but then i found it that this causes problems when you use the leftView/rightView properties, so its better tune the super's implementation, because it will take the left/right view's into account.

- (CGRect)textRectForBounds:(CGRect)bounds {
    CGRect ret = [super textRectForBounds:bounds];
    ret.origin.x = ret.origin.x + 5;
    ret.size.width = ret.size.width - 10;
    return ret;
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}
Stoto
  • 410
  • 4
  • 10
6

Set padding for UITextField with UITextBorderStyleNone: Swift

Based on @Evil Trout's most voted answer I created a custom method in my ViewController class, like shown bellow:

- (void) modifyTextField:(UITextField *)textField
{
    UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
    textField.leftView = paddingView;
    textField.leftViewMode = UITextFieldViewModeAlways;
    textField.rightView = paddingView;
    textField.rightViewMode = UITextFieldViewModeAlways;

    [textField setBackgroundColor:[UIColor whiteColor]];
    [textField setTextColor:[UIColor blackColor]];
}

Now I can call that method inside (viewDidLoad method) and send any of my TextFields to that method and add padding for both right and left, and give text and background colors by writing just one line of code, as follows:

[self modifyTextField:self.firstNameTxtFld];

This Worked perfectly on iOS 7! I know that adding too much Views might make this a bit heavier class to be loaded. But when concerned about the difficulty in other solutions, I found myself more biased to this method and more flexible with using this way. ;)

Thanks for the Hack "Evil Trout"! (bow)

I thought I should update this answer's code snippet with Swift:

Since Swift allow us to write extensions for the existing classes, let's write it in that way.

extension UITextField {
    func addPaddingToTextField() {
        let paddingView: UIView = UIView.init(frame: CGRectMake(0, 0, 8, 20))
        self.leftView = paddingView;
        self.leftViewMode = .Always;
        self.rightView = paddingView;
        self.rightViewMode = .Always;

    
        self.backgroundColor = UIColor.whiteColor()
        self.textColor = UIColor.blackColor()
    }
}

Usage:

self.firstNameTxtFld.addPaddingToTextField()

Hope this would be helpful to somebody else out there!
Cheers!

Community
  • 1
  • 1
Randika Vishman
  • 7,157
  • 3
  • 55
  • 75
6

Updated version for Swift 3:

@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)
    }
}
Beninho85
  • 2,977
  • 23
  • 21
5

Here's how to achieve this in SWIFT

@IBOutlet weak var yourTextField: UITextField!

override func viewDidLoad() {
super.viewDidLoad()
let paddingView = UIView(frame: CGRectMake(0, 0, 10, self.yourTextField.frame.height))
yourTextField.leftView = paddingView
yourTextField.leftViewMode = UITextFieldViewMode.Always
}
}

Resource

DrPatience
  • 1,516
  • 2
  • 13
  • 33
5

Swift 2.0 Version:

let paddingView: UIView = UIView(frame: CGRectMake(0, 0, 5, 20))
textField.leftView = paddingView
textField.leftViewMode = UITextFieldViewMode.Always;
Phil
  • 3,683
  • 1
  • 34
  • 37
5

If anyone is looking for Swift 4.0 version then below extension is work. It has both Left and Right padding for UITextField. Actually it is IBInspectable for storyboard configuration. You can set the value directly from the Interface Builder / Storyboard. This is tested code in Swift 4.0 version and Xcode 9.0

Keep in mind that if you want to enable Clear Button on the same UITextField then your have to keep Right Padding blank.

import UIKit

extension UITextField {

    @IBInspectable var paddingLeft: CGFloat {
        get {
            return leftView!.frame.size.width
        }
        set {
            let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
            leftView = paddingView
            leftViewMode = .always
        }
    }

    @IBInspectable var paddingRight: CGFloat {
        get {
            return rightView!.frame.size.width
        }
        set {
            let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
            rightView = paddingView
            rightViewMode = .always     
        }
    }
}  
Bhavin_m
  • 2,622
  • 3
  • 27
  • 46
4

^ these suggestions are great for those who are programmatically creating an interface.

But there are two LAZY EASY WAYS for those of us who use the Xcode interface builder:

  • easier: put a UIImageView behind a text field

  • easiest: change the border style on your to the simple black square (second from left option), then add your image as a background image. The image takes precedence over the square, so you still get the padding needed for a normal image background, without the square actually being drawn on.

EDIT: you can also use the black sphere (third from left option when selecting the UITextBox in IB), it does not work with the far right, "graphical sphere" style.

woody121
  • 358
  • 3
  • 13
  • Your easier solution is indeed a valid choice in some cases, but your easiest solution is a hack, which also does not work if your image's edge pixels have variable alpha (not to mention that Apple could change their implementation in a future iOS release). – jmdecombe Feb 04 '15 at 20:44
  • I don't disagree with you - thats why I put "lazy easy way" in all caps letters. Its worked fine for me to date. – woody121 Feb 05 '15 at 02:54
3

The best way to do this is simply make a class using subclass of UITextField and in .m file

 #import "CustomTextField.h"
 #import <QuartzCore/QuartzCore.h>
 @implementation CustomTextField


- (id)initWithCoder:(NSCoder*)coder 
 {
  self = [super initWithCoder:coder];

  if (self) {

//self.clipsToBounds = YES;
//[self setRightViewMode:UITextFieldViewModeUnlessEditing];

self.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,15,46)];
self.leftViewMode=UITextFieldViewModeAlways;
   }

  return self;

 }

by doing this go to your storyboard or xib and click on identity inspector and replace UITextfield with your own "CustomTextField" in class option.

Note: If you simply give padding with auto layout for textfield then your application will not run and show only blank screen.

Anuj Kumar Rai
  • 666
  • 1
  • 6
  • 16
3

Swift 3 Version:

class CustomTextField:UITextField{

    required init?(coder aDecoder: NSCoder){
        super.init(coder: aDecoder)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect.init(x: bounds.origin.x + 8, y: bounds.origin.y, width: bounds.width, height: bounds.height)
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return self.textRect(forBounds:bounds)
    }
}
王怡飞
  • 829
  • 1
  • 12
  • 15
2

Nate Flink's answer is my favourite, but don't forget about right/left views. E.g for UITextField subclass:

override func rightViewRectForBounds(bounds: CGRect) -> CGRect {
    let rightViewBounds = super.rightViewRectForBounds(bounds)

    return CGRectMake(CGRectGetMinX(rightViewBounds) - 10, CGRectGetMinY(rightViewBounds), CGRectGetWidth(rightViewBounds), CGRectGetHeight(rightViewBounds))
}

Above code set right padding for rightView of UITextField.

Community
  • 1
  • 1
rafalkitta
  • 492
  • 6
  • 9
2

Swift 3 Solution

class CustomTextField: UITextField {

 override func textRect(forBounds bounds: CGRect) -> CGRect {
  return CGRect(x: bounds.origin.x + 10, y: bounds.origin.y + 8, width: bounds.size.width - 20, height: bounds.size.height - 16)
 }

 override func editingRect(forBounds bounds: CGRect) -> CGRect {
  return self.textRect(forBounds: bounds)
 }
}
Ben Sullivan
  • 1,955
  • 1
  • 15
  • 31
2

Here is a Swift code to give padding in UITextfield

 func txtPaddingVw(txt:UITextField) {
     let paddingView = UIView(frame: CGRectMake(0, 0, 10, 10))
     txt.leftViewMode = .Always
     txt.leftView = paddingView
 }

and call using

self.txtPaddingVw(txtPin)
Hardik Thakkar
  • 13,424
  • 2
  • 80
  • 72
2

you can use category. set padding to left and right

UITextField+Padding.h

@interface UITextField (Padding)
@property (nonatomic, assign) CGFloat paddingValue;
@property (nonatomic, assign) CGFloat leftPadding;
@property (nonatomic, assign) CGFloat rightPadding;

//overwrite
-(CGRect)textRectForBounds:(CGRect)bounds;
-(CGRect)editingRectForBounds:(CGRect)bounds;
@end

UITextField+Padding.m

#import "UITextField+Padding.h"
#import <objc/runtime.h>

static char TAG_LeftPaddingKey;
static char TAG_RightPaddingKey;
static char TAG_Left_RightPaddingKey;

@implementation UITextField (Padding)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
-(CGRect)textRectForBounds:(CGRect)bounds {

CGFloat offset_Left=0;
CGFloat offset_Right=0;
if (self.paddingValue>0) {
    offset_Left=self.paddingValue;
    offset_Right=offset_Left;
}else{
    if (self.leftPadding>0){
        offset_Left=self.leftPadding;
    }
    if (self.rightPadding>0){
        offset_Right=self.rightPadding;
    }
}

if (offset_Left>0||offset_Right>0) {
    return CGRectMake(bounds.origin.x+ offset_Left ,bounds.origin.y ,
                      bounds.size.width- (offset_Left+offset_Right), bounds.size.height-2 );
 }else{
    return bounds;
 }
}



-(CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}
#pragma clang diagnostic pop


#pragma maek -setter&&getter
- (CGFloat)paddingValue
{
    return [objc_getAssociatedObject(self,&TAG_Left_RightPaddingKey) floatValue];
}
-(void)setPaddingValue:(CGFloat)paddingValue
{
    objc_setAssociatedObject(self, &TAG_Left_RightPaddingKey, @(paddingValue), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(CGFloat)leftPadding
{
    return [objc_getAssociatedObject(self,&TAG_LeftPaddingKey) floatValue];
}

-(void)setLeftPadding:(CGFloat)leftPadding
{
    objc_setAssociatedObject(self, &TAG_LeftPaddingKey, @(leftPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(CGFloat)rightPadding
{
    return [objc_getAssociatedObject(self,&TAG_RightPaddingKey) floatValue];
}

-(void)setRightPadding:(CGFloat)rightPadding
{
    objc_setAssociatedObject(self, &TAG_RightPaddingKey, @(rightPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

you can set padding like this self.phoneNumTF.paddingValue=10.f; or self.phoneNumTF.leftPadding=10.f;

rikiluo
  • 21
  • 5
1

@Evil trout's answer is great. I have been using this approach for quite a some time now. The only thing it lacks is "dealing with numerous text fields". I tried other approaches but does not seem to work.

Subclassing UITextField just to add a padding didn't make any sense to me. So, I iterated over all UITextFields to add the padding.

-(void) addPaddingToAllTextFields:(UIView*)view {

    for(id currentView in [view subviews]){
        if([currentView isKindOfClass:[UITextField class]]) {
            // Change value of CGRectMake to fit ur need
            [currentView setLeftView:[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 20)]];
            [currentView setLeftViewMode:UITextFieldViewModeAlways];
        }

        if([currentView respondsToSelector:@selector(subviews)]){
            [textfieldarray addObjectsFromArray:[self addPaddingToAllTextFields:currentView]];
        }
    }
}
Kishor Kundan
  • 3,029
  • 1
  • 21
  • 30
  • the method can be called by [self addPaddingToAllTextFields:[self view]]; – Kishor Kundan Oct 25 '13 at 06:44
  • Since `textfieldarray` isn't defined in the second `if` block, I used this snippet (thanks!) with success after replacing the contents of the second `if` with `for(id subSubView in [view subviews]){[self addPaddingToAllTextFields:subSubView];}` – adamup Nov 21 '13 at 01:34
1

Brody's solution worked perfect for me. I have had to add side views on a textfield and add additional padding. So by implementing the custom UIEdgeInsets property to a UITextField subclass I have managed to achieve the task. I'm going to use this new subclass in all of my projects.

Lubakis
  • 141
  • 8
1

The best solution I found so far is a category. That's how I add a 5 points padding to left and right:

@implementation UITextField (Padding)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (CGRect)textRectForBounds:(CGRect)bounds {
    return CGRectMake(bounds.origin.x + 5, bounds.origin.y,
                      bounds.size.width - 10, bounds.size.height);
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}
#pragma clang diagnostic pop

@end

The #pragma's are just for removing the annoying warnings

Mongi Zaidi
  • 1,059
  • 10
  • 15
  • The thing with method overloading in categories is, that it will be marked as unused in AppCode, which it is in fact. Good idea, but not very secure because it is easily removed when you run "Optimize imports" (no problem for Xcode users though, but we all know the limited code-centric features) – Sebastian Wramba Feb 12 '14 at 10:20
  • 1
    Is it a simple bummer category that will apply padding for all text fields in the app? – Ben Affleck May 12 '14 at 17:45
  • @Andy no it applies only when you import it, you will need to create a class UITextField+Padding and import it in the viewcontroller or class you have a textfield with padding – Mongi Zaidi May 12 '14 at 17:55
  • @MongiZaidi: you are wrong. It gets linked into the executable, whether being imported is irrelevant. – Zsolt Szatmari Dec 16 '16 at 11:15
1
textField.layer.borderWidth = 3;

will add border, which worked as padding for me.

Saqib Saud
  • 2,779
  • 2
  • 25
  • 41
0

Another consideration is that, if you have more than one UITextField where you are adding padding, is to create a separate UIView for each textfield - because they cannot be shared.

Paras Joshi
  • 19,954
  • 11
  • 54
  • 69
user1686700
  • 758
  • 1
  • 5
  • 5
0

Why not Attributed String !?!, this is one of the blessing feature of IOS 6.0 :)

NSMutableParagraphStyle *mps = [[NSMutableParagraphStyle alloc] init];
            mps.firstLineHeadIndent = 5.0f;
UIColor *placeColor = self.item.bgColor;

textFieldInstance.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"My Place Holder" attributes:@{NSForegroundColorAttributeName: placeColor, NSFontAttributeName : [UIFont systemFontOfSize:7.0f], NSParagraphStyleAttributeName : mps}];
-1

I found it far easier to use a non-editable UITextView and set the contentOffset

uiTextView.contentOffset = CGPointMake(8, 7);
Paras Joshi
  • 19,954
  • 11
  • 54
  • 69
seenickcode
  • 612
  • 5
  • 13