Définir le remplissage pour UITextField avec UITextBorderStyleNone

399

Je voulais utiliser un arrière-plan personnalisé pour mon UITextFields . Cela fonctionne bien, sauf pour le fait que je dois l'utiliser UITextBorderStyleNonepour le rendre joli. Cela force le texte à rester à gauche sans aucun remplissage.

Puis-je définir un remplissage manuellement afin qu'il ressemble à, UITextBorderStyleRoundedRectsauf pour utiliser mon image d'arrière-plan personnalisée?

Sebastian Wramba
la source

Réponses:

838

J'ai trouvé un petit hack soigné pour régler le rembourrage gauche pour cette situation exacte.

Fondamentalement, vous définissez la propriété leftView de la UITextFieldpour être une vue vide de la taille du remplissage souhaité:

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

A fonctionné à merveille pour moi!

Dans Swift 3 / Swift 4 , cela peut être fait en faisant cela

let paddingView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 5, height: 20))
textField.leftView = paddingView
textField.leftViewMode = .always
Truite maléfique
la source
1
Exactement ce dont j'avais besoin, sauf que j'avais besoin d'un rembourrage à droite, ce qui est essentiellement le même, bien sûr. Merci!
cg.
@Lukasz J'ai ajouté une libération automatique à cette réponse, la réponse acceptée. Première ligne. EDIT: oups, peut-être que je n'ai pas enregistré? ou ma modification a été rejetée? Quoi qu'il en soit, Vincent a ajouté une version automatique, alors oui pour cela!
Eric Goldberg
1
En utilisant ARC, pourquoi mon application se bloque-t-elle et utilise-t-elle beaucoup de CPU si je réutilise *paddingViewavec plusieurs champs de texte?
The Muffin Man
3
C'est une mauvaise solution, mieux vaut opter pour celle de Nate Flink. Thios one n'inclut pas le remplissage en mode éditiong.
Jacek Kwiecień
3
Il ne fonctionne pas avec plusieurs champs de texte. Consomme juste tellement de mémoire et se bloque plus tard.
cage à oiseaux
177

J'ai créé cette implémentation de catégorie et l'ai ajoutée en haut du .mfichier.

@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

Basé sur le lien fourni par Piotr Blasiak. Il semblait plus simple que de créer une toute nouvelle sous-classe, et aussi plus simple que d'ajouter l'ajout UIView. Pourtant, il semble que quelque chose manque pour ne pas pouvoir contrôler le remplissage à l'intérieur d'un champ de texte.

Solution Swift 4:

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)
    }
}
Nate Flink
la source
6
Cela déclenche des avertissements sur les méthodes remplaçant les catégories. Voir cette réponse pour les supprimer.
pdenya
5
Je préfère ne pas faire cela dans une catégorie, mais à part ça, c'est une solution plus propre que la réponse acceptée.
Bob Vork
2
Il vaut mieux utiliser CGRectInset () pour quelque chose comme ça, au lieu de rouler le vôtre. C'est aussi un peu plus propre: retournez CGRectInset (limites, 10, 8);
Dennis Munsie
1
@shashwat oui, vous pouvez spécifier n'importe quel rembourrage que vous souhaitez
Ege Akpinar
1
Lorsque j'ai ajouté cela il y a 4 ans, les choses étaient différentes avec iOS, et je conviens que maintenant il est préférable de créer une sous-classe. Cependant, si vous voulez juste un moyen rapide et sale d'inspecter visuellement vos distances en pixels, cela le fera;) Donc, ça va pour les gens de continuer à voter !!
Nate Flink
139

Une version Swift 3 pour Xcode> 6, où vous pouvez modifier la valeur de l'encart dans 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)
    }

}

entrez la description de l'image ici

bandejapaisa
la source
1
Je ne vois pas le champ de texte du formulaire sur le mien.
okysabeni
2
Je devais ajouter cette ligneoverride func placeholderRectForBounds(bounds: CGRect) -> CGRect { return CGRectInset(bounds, inset, inset) }
Michael
2
Cette réponse serait plus utile avec une explication ou un lien vers une explication de quoi @IBDesignableet @IBInspectablefaire, c'est-à-dire ce poste à nshipster
Russell Austin
1
Si vous comptez sur des vues d'accessoires (telles que la fonctionnalité de bouton d'effacement sur UITextField), alors return super.textRectForBounds(CGRectInset(bounds, inset, inset))gérera correctement le décalage par rapport aux vues d'accessoires.
Mike Fay
@okysabeni vous devez cliquer sur votre champ de texte et changer la classe en FormTextField
Gustavo Barbosa
77

Edit: fonctionne toujours dans iOS 11.3.1

Dans iOS 6 myTextField.leftView = paddingView;est à l'origine du problème

Cela résout le problème

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

Pour l'utilisation du champ de texte aligné à droite CATransform3DMakeTranslation(-5, 0, 0)comme mentionné par latenitecoder dans les commentaires

Inder Kumar Rathore
la source
1
Bien, j'ai dû mettre le rembourrage dans tous les champs de texte de l'application, j'ai créé une catégorie de UITextField et mis ce code à l'intérieur - (void) awakeFromNib {} et cela a résolu mon problème
Teena nath Paul
Si simple! Thx :) J'ai une question comment puis-je créer un code simple pour créer tous les UITextField au lieu d'écrire le code plusieurs fois?
Luai Kalkatawi
1
Tous les autres commentaires supposent que vous souhaitez remplir un UITextField à partir de la gauche. Le sous-classement est beaucoup de surcharge pour ajouter un identifiant d'espacement plutôt que d'ajouter quelques caractères vierges, mais cette solution est LA solution. Une ligne à l'épreuve du temps. Si vous travaillez avec un champ de texte aligné à droite, utilisez la valeur moins (-5,0,0) Merci Inder
latenitecoder
1
Après 4 ans, j'ai trouvé ma propre réponse: D, @latenitecoder votre commentaire était ce qui était nécessaire. Mise à jour de la réponse
Inder Kumar Rathore
1
que puis-je faire si je veux un rembourrage droit et gauche ??
Mina Hanna
70

Une bonne approche pour ajouter un remplissage à UITextField consiste à sous-classer et à ajouter une propriété edgeInsets. Vous définissez ensuite les edgeInsets et le UITextField sera dessiné en conséquence. Cela fonctionnera également correctement avec un ensemble leftView ou rightView personnalisé.

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
la source
Cette réponse devrait être acceptée. Il fonctionne également pour les vues droite et gauche ..
NSPratik
25

Il suffit de sous-classer UITextField comme ceci:

@implementation DFTextField


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

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


@end

Cela ajoute un rembourrage horizontal de 10 points de chaque côté.

Camsoft
la source
21

Code objectif C

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

entrez la description de l'image ici

Kirit Vaghela
la source
20
  1. Créer un champ de texte personnalisé

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. Définissez votre classe de champ de texte sur PaddingTextField et personnalisez votre remplissage à votre guise entrez la description de l'image ici entrez la description de l'image ici

  2. Profitez-en

final

777Q
la source
19

Sur la base de la réponse d'Evil Trout, vous voudrez peut-être créer une catégorie pour la rendre plus facile à utiliser dans plusieurs applications.

En tête de fichier:

@interface UITextField (PaddingText)

-(void) setLeftPadding:(int) paddingValue;

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

Fichier d'implémentation:

#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

Exemple d'utilisation

#import "UITextField+PaddingText.h"

[self.YourTextField setLeftPadding:20.0f];

J'espère que ça vous aide les gars

À votre santé

Paulo Miguel Almeida
la source
14

Version Swift:

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)
        }
    }
}

Pour que vous puissiez attribuer une valeur dans IB

Paramètre IBInspectable représenté dans Interface Builder

superarts.org
la source
IBInspectablevous permet d'appliquer le code setter lors de l'exécution, il vous suffit donc de saisir votre numéro Interface Builderet cela fonctionnera.
superarts.org
Cela ne fonctionnera pas lorsque vous l'avez Clear Button. Votre bouton clair ne sera pas visible si vous appliquez cette solution.
Bhavin_m
11

Vous ne pouvez pas définir de rembourrage. Au lieu de cela, ayez un UIViewqui a votre image de fond et l' UITextFieldintérieur de celui-ci. Définissez la UITextFieldlargeur comme UIViewWidth-(paddingSize x 2)et la hauteur de manière similaire, puis définissez-la au point paddingSize,paddingSize.

Thomas Clayson
la source
10

Il suffit de sous- classer UITextField comme ceci ( version Swift ):

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)
    }

}

Cela ajoute un rembourrage horizontal de 25,0 points de chaque côté.

Roi-sorcier
la source
8

J'étais basé sur la solution de Nate, mais j'ai trouvé que cela causait des problèmes lorsque vous utilisez les propriétés leftView / rightView, donc il vaut mieux régler l'implémentation du super, car il prendra en compte les vues gauche / droite.

- (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
la source
6

Version mise à jour pour 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
la source
6

Définir le remplissage pour UITextField avec UITextBorderStyleNone: Swift

Sur la base de la réponse la plus votée de @Evil Trout, j'ai créé une méthode personnalisée dans ma classe ViewController, comme indiqué ci-dessous:

- (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]];
}

Maintenant, je peux appeler cette méthode à l'intérieur (méthode viewDidLoad) et envoyer n'importe lequel de mes TextFields à cette méthode et ajouter un remplissage pour la droite et la gauche, et donner des couleurs de texte et d'arrière-plan en écrivant une seule ligne de code, comme suit:

[self modifyTextField:self.firstNameTxtFld];

Cela a parfaitement fonctionné sur iOS 7! Je sais que l'ajout de trop de vues pourrait rendre cette classe un peu plus lourde à charger. Mais soucieux de la difficulté des autres solutions, je me suis retrouvé plus partisan de cette méthode et plus flexible à utiliser de cette façon. ;)

Merci pour le Hack "Evil Trout"! (arc)

J'ai pensé que je devrais mettre à jour l'extrait de code de cette réponse avec Swift:

Puisque Swift nous permet d'écrire des extensions pour les classes existantes, écrivons-le de cette façon.

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()

J'espère que cela serait utile à quelqu'un d'autre!
À votre santé!

Randika Vishman
la source
5

Voici comment y parvenir dans 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
}
}

Ressource

DrPatience
la source
5

Version Swift 2.0:

let paddingView: UIView = UIView(frame: CGRectMake(0, 0, 5, 20))
textField.leftView = paddingView
textField.leftViewMode = UITextFieldViewMode.Always;
Phil
la source
4

^ ces suggestions sont idéales pour ceux qui créent une interface par programmation.

Mais il y a deux LAZY EASY WAYS pour ceux d'entre nous qui utilisent le constructeur d'interface Xcode:

  • plus facile: placez une UIImageView derrière un champ de texte

  • le plus simple: changez le style de bordure sur votre en un simple carré noir (deuxième option à partir de la gauche), puis ajoutez votre image comme image de fond. L'image est prioritaire sur le carré, vous obtenez donc toujours le remplissage nécessaire pour un arrière-plan d'image normal, sans que le carré soit réellement dessiné.

EDIT: vous pouvez également utiliser la sphère noire (troisième option en partant de la gauche lors de la sélection de l'UITextBox dans IB), elle ne fonctionne pas avec le style extrême "sphère graphique".

woody121
la source
Votre solution la plus simple est en effet un choix valable dans certains cas, mais votre solution la plus simple est un hack, qui ne fonctionne pas non plus si les pixels de bord de votre image ont un alpha variable (sans oublier qu'Apple pourrait changer leur implémentation dans une future version iOS).
jmdecombe
Je ne suis pas en désaccord avec vous - c'est pourquoi j'ai mis "paresseux facile" dans toutes les lettres majuscules. À ce jour, cela a bien fonctionné pour moi.
woody121
4

Si quelqu'un est à la recherche d'une Swift 4.0version, le extensiontravail est ci - dessous . Il a les deux Leftet un Rightrembourrage pour UITextField. En fait, c'est IBInspectablepour la configuration du storyboard. Vous pouvez définir la valeur directement depuis Interface Builder / Storyboard. Ce code est testé dans la version Swift 4.0 et Xcode 9.0

Gardez à l'esprit que si vous souhaitez activer Clear Buttonla même chose, UITextFieldvous devez garder le remplissage droit vide.

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
la source
3

La meilleure façon de le faire est simplement de créer une classe en utilisant la sous-classe de UITextField et dans un fichier .m

 #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;

 }

en faisant cela, allez dans votre storyboard ou xib et cliquez sur l'inspecteur d'identité et remplacez UITextfield par votre propre option "CustomTextField" dans la classe.

Remarque: Si vous donnez simplement un remplissage avec une mise en page automatique pour le champ de texte, votre application ne s'exécutera pas et n'affichera qu'un écran vide.

Anuj Kumar Rai
la source
3

Version Swift 3:

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)
    }
}
王怡飞
la source
2

La réponse de Nate Flink est ma préférée, mais n'oubliez pas les vues droite / gauche. Par exemple, pour la UITextFieldsous-classe:

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

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

Au-dessus du code, réglez le remplissage droit pour rightViewof UITextField.

rafalkitta
la source
2

Solution Swift 3

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
la source
2

Voici un code Swift pour donner un remplissage dans UITextfield

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

et appeler en utilisant

self.txtPaddingVw(txtPin)
Hardik Thakkar
la source
2

vous pouvez utiliser la catégorie. définir le rembourrage à gauche et à droite

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

vous pouvez définir un remplissage comme celui-ci self.phoneNumTF.paddingValue = 10.f; ou self.phoneNumTF.leftPadding = 10.f;

rikiluo
la source
1

La réponse de @Evil trout est excellente. J'utilise cette approche depuis un certain temps maintenant. La seule chose qui lui manque est "de traiter de nombreux champs de texte". J'ai essayé d'autres approches mais ne semble pas fonctionner.

Sous-classer UITextField juste pour ajouter un remplissage n'a pas de sens pour moi. J'ai donc itéré sur tous les UITextFields pour ajouter le remplissage.

-(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
la source
la méthode peut être appelée par [self addPaddingToAllTextFields: [self view]];
Kishor Kundan
Puisqu'il textfieldarrayn'est pas défini dans le deuxième ifbloc, j'ai utilisé cet extrait (merci!) Avec succès après avoir remplacé le contenu du second ifparfor(id subSubView in [view subviews]){[self addPaddingToAllTextFields:subSubView];}
adamup
1

La solution de Brody a fonctionné parfaitement pour moi. J'ai dû ajouter des vues latérales sur un champ de texte et ajouter un remplissage supplémentaire. Donc, en implémentant la propriété UIEdgeInsets personnalisée dans une sous-classe UITextField, j'ai réussi à accomplir la tâche. Je vais utiliser cette nouvelle sous-classe dans tous mes projets.

Lubakis
la source
1

La meilleure solution que j'ai trouvée jusqu'à présent est une catégorie. Voilà comment j'ajoute un rembourrage de 5 points à gauche et à droite:

@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

Les # pragma sont juste pour supprimer les avertissements gênants

Mongi Zaidi
la source
Le problème avec la surcharge de méthode dans les catégories, c'est qu'elle sera marquée comme inutilisée dans AppCode, ce qu'elle est en fait. Bonne idée, mais pas très sécurisée car elle est facilement supprimée lorsque vous exécutez "Optimiser les importations" (pas de problème pour les utilisateurs de Xcode cependant, mais nous connaissons tous les fonctionnalités limitées centrées sur le code)
Sebastian Wramba
1
S'agit-il d'une simple catégorie décevante qui appliquera un remplissage pour tous les champs de texte de l'application?
Ben Sinclair
@Andy non, il ne s'applique que lorsque vous l'importez, vous devrez créer une classe UITextField + Padding et l'importer dans le viewcontroller ou la classe dont vous avez un champ de texte avec padding
Mongi Zaidi
@MongiZaidi: vous vous trompez. Il est lié à l'exécutable, que l'importation soit sans importance.
Zsolt Szatmari
1
textField.layer.borderWidth = 3;

ajoutera une bordure, qui a fonctionné comme rembourrage pour moi.

Saqib Saud
la source
0

Une autre considération est que, si vous en avez plusieurs UITextFieldoù vous ajoutez un remplissage, vous devez en créer un distinct UIViewpour chaque champ de texte, car ils ne peuvent pas être partagés.

user1686700
la source