Set padding for UITextField with UITextBorderStyleNone
Asked Answered
C

32

419

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?

Catarinacatarrh answered 16/9, 2010 at 13:21 Comment(0)
S
876

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
Shandy answered 12/12, 2010 at 20:20 Comment(15)
Exactly what I needed, except I needed padding to the right which is mostly the same, of course. Thanks!Lemmuela
@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!Chrysoberyl
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?Transverse
Using ARC, why does my app hang and use a lot of CPU if I reuse *paddingView with multiple text fields?Gershom
It's a bad solution, better go for Nate Flink's one. Thios one doesn't include editiong mode padding.Insurer
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: https://mcmap.net/q/86063/-set-padding-for-uitextfield-with-uitextborderstylenoneAntipas
It is not working with multiple textfields. Just consumes so much memory and later crashes.Cirenaica
@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.Sometime
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.Whitlow
@coco yes, i am having this issue but why so?? i ended up subclassing UITextField, & it worked.Aura
@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..)Stomato
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...Stigmatize
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.Alchemy
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?Panegyric
700 ups (I would up it again if I can) because it works as a hack. If you're using the leftView for something then you... need another solution ;)Cabob
D
184

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)
    }
}
Dactylogram answered 20/6, 2011 at 19:16 Comment(6)
This throws warnings about categories overriding methods. See this answer to suppress them.Lyublin
I prefer not doing this in a category, but other than that this is a cleaner solution than the accepted answer.Starlight
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);Varrian
@EgeAkpinar but what if we want different padding in all four sides ..? Can we use CGRectInset in this case ..?Jaredjarek
@Jaredjarek yes, you can specify any padding you'd wantMorita
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!!Dactylogram
B
147

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

Bowhead answered 18/12, 2014 at 18:28 Comment(9)
I don't see the form text field on mine.Owl
I needed to add this line override func placeholderRectForBounds(bounds: CGRect) -> CGRect { return CGRectInset(bounds, inset, inset) }Hembree
This answer would be more helpful with an explanation or link to explanation of what @IBDesignable and @IBInspectable do, i.e. this post at nshipsterRustle
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.Interdependent
@okysabeni you need to click on your textfield and change the Class to FormTextFieldRani
Swift 3 > Go to "Show Identity Inspector" Add your "Custom Class". In this example. Add "FormTextField" in Custom Class.Vexillum
This should be the selected answer, because it does not cause the text to jump around when editing starts like the accepted answer does.Carmella
About textRect(forBounds: bounds), the documentation explicitly mentions not to call it directly: developer.apple.com/documentation/uikit/uitextfield/…Steere
@Steere If you look at the code, this isn't happening and it's not calling the super method that the documentation states not to call. You're instructed to override it, which is what is happening, and then editingRect is calling the overridden version, which in turn just calls bounds.insetBy.Bowhead
U
79

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

Unlikelihood answered 27/5, 2014 at 10:24 Comment(8)
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 problemTwentyfour
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?Pantechnicon
Yeah I have read that comment but couldn't know how and where to write it. @InderKumarRathorePantechnicon
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 InderSatiated
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)Universalist
After 4yrs I found my own answer :D , @Satiated your comment was what is needed. Updating the answerUnlikelihood
what can i do if i want both right and left padding ??Deedee
This gives me problems when using the textfield in password mode + when the text will get longer than the frame and the punctuation starts.Caste
C
71

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
Casta answered 9/7, 2013 at 21:22 Comment(1)
This should be accepted answer. It also works for right and left views..Seabrooke
B
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.

Brotherton answered 8/8, 2013 at 9:50 Comment(0)
B
23
  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

Bowknot answered 11/8, 2015 at 3:18 Comment(0)
S
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

Santo answered 28/4, 2015 at 5:35 Comment(2)
developer.apple.com/library/ios/recipes/…Huxley
About [self textRectForBounds:bounds];, the documentation explicitly mentions not to call it directly: developer.apple.com/documentation/uikit/uitextfield/…Steere
E
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

Evensong answered 20/1, 2014 at 18:5 Comment(0)
B
16

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

Bedfordshire answered 10/10, 2014 at 0:47 Comment(2)
IBInspectable allows you to apply the setter code at runtime, so simply put your number in Interface Builder and it will work.Bedfordshire
This will not work when you have Clear Button. Your clear button will not visible if apply this solution.Reaper
D
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.

Doable answered 16/9, 2010 at 13:35 Comment(0)
P
11

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.

Pun answered 22/11, 2014 at 0:0 Comment(0)
T
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];
}
Tiffinytiffy answered 16/1, 2013 at 11:47 Comment(0)
T
7

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)
    }
}
Tradeswoman answered 19/10, 2016 at 13:24 Comment(0)
A
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!

Antipas answered 18/3, 2014 at 5:33 Comment(0)
H
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

Heaveho answered 6/5, 2015 at 8:47 Comment(0)
C
5

Swift 2.0 Version:

let paddingView: UIView = UIView(frame: CGRectMake(0, 0, 5, 20))
textField.leftView = paddingView
textField.leftViewMode = UITextFieldViewMode.Always;
Candytuft answered 15/12, 2015 at 9:1 Comment(0)
R
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     
        }
    }
}  
Reaper answered 31/7, 2018 at 9:53 Comment(0)
B
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.

Baresark answered 21/3, 2013 at 21:36 Comment(2)
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).Keheley
I don't disagree with you - thats why I put "lazy easy way" in all caps letters. Its worked fine for me to date.Baresark
P
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.

Peek answered 19/3, 2015 at 8:29 Comment(0)
A
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)
    }
}
Algicide answered 29/9, 2017 at 6:0 Comment(0)
R
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.

Ruth answered 23/5, 2016 at 8:34 Comment(0)
W
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)
 }
}
Wheatley answered 23/8, 2016 at 11:14 Comment(0)
N
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)
Niobous answered 13/9, 2016 at 9:5 Comment(0)
A
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;

Aegean answered 17/11, 2016 at 3:56 Comment(0)
H
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]];
        }
    }
}
Hardner answered 25/10, 2013 at 6:43 Comment(2)
the method can be called by [self addPaddingToAllTextFields:[self view]];Hardner
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];}Bergen
G
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.

Giovannagiovanni answered 3/2, 2014 at 13:17 Comment(0)
S
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

Scyros answered 11/2, 2014 at 15:9 Comment(4)
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)Catarinacatarrh
Is it a simple bummer category that will apply padding for all text fields in the app?Stoeber
@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 paddingScyros
@MongiZaidi: you are wrong. It gets linked into the executable, whether being imported is irrelevant.Njord
L
0

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

uiTextView.contentOffset = CGPointMake(8, 7);
Lp answered 29/3, 2012 at 14:19 Comment(2)
uiTextView.contentOffset = CGPointMake(-8, -7);Elaineelam
There is no contentOffset property in UITextField. Maybe a misunderstood of UITextView.Justification
R
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.

Ruminate answered 12/12, 2012 at 21:47 Comment(0)
H
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}];
Hazlip answered 15/7, 2013 at 4:41 Comment(0)
L
0
textField.layer.borderWidth = 3;

will add border, which worked as padding for me.

Layamon answered 31/8, 2015 at 7:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.