web-dev-qa-db-fra.com

Indenter le texte dans un UITextField

Ma question est aussi simple que le titre, mais voici un peu plus:

J'ai un UITextField, sur lequel j'ai défini l'image d'arrière-plan. Le problème est que le texte épouse parfaitement son bord, qui est également le bord de l'image. Je souhaite que mon champ de texte ressemble à celui d'Apple, avec un peu d'espace horizontal entre l'image d'arrière-plan et le début du texte.

74
Dyldo42

C'est le moyen le plus rapide que j'ai trouvé sans faire aucune sous-classe:

UIView *spacerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
[textfield setLeftViewMode:UITextFieldViewModeAlways];
[textfield setLeftView:spacerView];

En rapide:

let spacerView = UIView(frame:CGRect(x:0, y:0, width:10, height:10))
textField.leftViewMode = UITextFieldViewMode.Always
textField.leftView = spacerView
226
adjwilli

Vous devez sous-classer et écraser textRectForBounds: et éditionRectForBounds: Voici une sous-classe UITextfield avec un arrière-plan personnalisé et un remplissage vertical et horizontal:

@interface MyUITextField : UITextField 
@property (nonatomic, assign) float verticalPadding;
@property (nonatomic, assign) float horizontalPadding;
@end

#import "MyUITextField.h"
@implementation MyUITextField
@synthesize horizontalPadding, verticalPadding;
- (CGRect)textRectForBounds:(CGRect)bounds {
    return CGRectMake(bounds.Origin.x + horizontalPadding, bounds.Origin.y + verticalPadding, bounds.size.width - horizontalPadding*2, bounds.size.height - verticalPadding*2);
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}
@end

Usage:

UIImage *bg = [UIImage imageNamed:@"textfield.png"];
CGRect rect = CGRectMake(0, 0, bg.size.width, bg.size.height);
MyUITextField *textfield = [[[MyUITextField alloc] initWithFrame:rect] autorelease];
textfield.verticalPadding = 10; 
textfield.horizontalPadding = 10;
[textfield setBackground:bg];
[textfield setBorderStyle:UITextBorderStyleNone];
[self.view addSubview:textfield];
41
Jano

Une bonne approche pour ajouter du remplissage à UITextField consiste à sous-classer UITextField, en remplaçant les méthodes rectangle et en ajoutant une propriété edgeInsets. Vous pouvez ensuite définir 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 = UIEdgeInsetsMake(0, 0, 0, 0);
    }
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if(self){
        self.edgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
    }
    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
26
Brody Robertson

J'ai transformé cela en une jolie petite extension à utiliser dans les Storyboards:

public extension UITextField {
    @IBInspectable public var leftSpacer:CGFloat {
        get {
            if let l = leftView {
                return l.frame.size.width
            } else {
                return 0
            }
        } set {
            leftViewMode = .Always
            leftView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
        }
    }
}
11
Oxcug

Mes 2 centimes:

class PaddedTextField : UITextField {
    var insets = UIEdgeInsets.zero
    var verticalPadding:CGFloat = 0
    var horizontalPadding:CGFloat = 0

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.Origin.x + insets.left, y: bounds.Origin.y + insets.top, width: bounds.size.width - (insets.left + insets.right), height: bounds.size.height - (insets.top + insets.bottom));
    }

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

Je suggère de convertir votre UITextField en UITextView et de définir le contentInset. Par exemple, indenter par 10 espaces:

textview.contentInset=UIEdgeInsetsMake(0, 10, 0, 0);
1
user790072

Si vous ne voulez pas créer @ IBOutlet, vous pouvez simplement créer une sous-classe (réponse en Swift):

class PaddedTextField: UITextField {

  override func awakeFromNib() {
      super.awakeFromNib()

      let spacerView = UIView(frame:CGRect(x: 0, y: 0, width: 10, height: 10))
      leftViewMode = .always
      leftView = spacerView
   }
}
0
Vrutin Rathod

Parfois, la vue de gauche du champ de texte est une image en forme de loupe d'Apple . Si c'est le cas, vous pouvez définir un retrait comme ceci:

    UIView *leftView = textField.leftView;
    if (leftView && [leftView isKindOfClass:[UIImageView class]]) {
        leftView.contentMode = UIViewContentModeCenter;
        leftView.width = 20.0f;  //the space you want indented.
    }
0
Lirik