Les vues leftView et rightView d'un UITextField sur iOS7 sont très proches de la bordure du champ de texte.
Comment puis-je ajouter du rembourrage (horizontal) à ces éléments?
J'ai essayé de modifier le cadre, mais cela n'a pas fonctionné
uint padding = 10;//padding for iOS7
UIImageView * iconImageView = [[UIImageView alloc] initWithImage:iconImage];
iconImageView.frame = CGRectMake(0 + padding, 0, 16, 16);
textField.leftView = iconImageView;
Veuillez noter que je ne suis pas intéressé par l'ajout de remplissage au texte du champ de texte, comme ceci Définir le remplissage pour UITextField avec UITextBorderStyleNone
Je travaillais juste sur cela moi-même et utilisais cette solution:
- (CGRect) rightViewRectForBounds:(CGRect)bounds {
CGRect textRect = [super rightViewRectForBounds:bounds];
textRect.Origin.x -= 10;
return textRect;
}
Cela déplacera l'image par la droite de 10 au lieu d'avoir l'image comprimée contre le bord dans iOS 7.
En outre, il s'agissait d'une sous-classe de UITextField
, qui peut être créée par:
UITextField
au lieu du fichier par défaut NSObject
Ajoutez une nouvelle méthode nommée - (id)initWithCoder:(NSCoder*)coder
pour définir l'image.
- (id)initWithCoder:(NSCoder*)coder {
self = [super initWithCoder:coder];
if (self) {
self.clipsToBounds = YES;
[self setRightViewMode:UITextFieldViewModeUnlessEditing];
self.leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"textfield_edit_icon.png"]];
}
return self;
}
Vous devrez peut-être importer #import <QuartzCore/QuartzCore.h>
Ajoutez la méthode rightViewRectForBounds
ci-dessus
Dans Interface Builder, cliquez sur le champ TextField que vous souhaitez sous-classer et remplacez l'attribut class par le nom de cette nouvelle sous-classe.
Une solution beaucoup plus simple, qui tire parti de contentMode
:
arrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"down_arrow"]];
arrow.frame = CGRectMake(0.0, 0.0, arrow.image.size.width+10.0, arrow.image.size.height);
arrow.contentMode = UIViewContentModeCenter;
textField.rightView = arrow;
textField.rightViewMode = UITextFieldViewModeAlways;
Dans Swift 2,
let arrow = UIImageView(image: UIImage(named: "down_arrow"))
arrow.frame = CGRectMake(0.0, 0.0, arrow.image.size.width+10.0, arrow.image.size.height);
arrow.contentMode = UIViewContentMode.Center
self.textField.rightView = arrow
self.textField.rightViewMode = UITextFieldViewMode.Always
Dans Swift 3,
let arrow = UIImageView(image: UIImage(named: "arrowDrop"))
if let size = arrow.image?.size {
arrow.frame = CGRect(x: 0.0, y: 0.0, width: size.width + 10.0, height: size.height)
}
arrow.contentMode = UIViewContentMode.center
self.textField.rightView = arrow
self.textField.rightViewMode = UITextFieldViewMode.always
Le moyen le plus simple est d’ajouter UIView à leftView/righView et d’ajouter un ImageView à UIView, de régler l’origine de ImageView dans UIView où vous voulez, cela m’a fonctionné comme un charme. Il ne nécessite que quelques lignes de code
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 5, 26, 26)];
imgView.image = [UIImage imageNamed:@"img.png"];
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
[paddingView addSubview:imgView];
[txtField setLeftViewMode:UITextFieldViewModeAlways];
[txtField setLeftView:paddingView];
Cela fonctionne très bien pour Swift:
let imageView = UIImageView(image: UIImage(named: "image.png"))
imageView.contentMode = UIViewContentMode.Center
imageView.frame = CGRectMake(0.0, 0.0, imageView.image!.size.width + 20.0, imageView.image!.size.height)
textField.rightViewMode = UITextFieldViewMode.Always
textField.rightView = imageView
Ça marche pour moi
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 20)];
self.passwordTF.leftView = paddingView;
self.passwordTF.leftViewMode = UITextFieldViewModeAlways;
Que cela vous aide.
J'aime cette solution car elle résout le problème avec une seule ligne de code
myTextField.layer.sublayerTransform = CATransform3DMakeTranslation(10.0f, 0.0f, 0.0f);
Remarque: .. ou 2 si vous envisagez d'inclure une ligne dans QuartzCore :)
La meilleure façon de faire est simplement de créer une classe en utilisant la sous-classe de UITextField et dans le 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, cliquez sur l'inspecteur d'identité et remplacez UITextfield par votre propre option "CustomTextField" in class.
Remarque: Si vous fournissez simplement un remplissage avec mise en page automatique pour le champ de texte, votre application ne s'exécutera pas et affichera uniquement un écran vide.
J'ai trouvé ça quelque part ...
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
paddingView.backgroundColor = [UIColor clearColor];
itemDescription.leftView = paddingView;
itemDescription.leftViewMode = UITextFieldViewModeAlways;
[self addSubview:itemDescription];
J'ai moi-même eu ce problème, et de loin la solution la plus simple est de modifier votre image pour ajouter simplement un rembourrage de chaque côté de l'image!
Je viens de modifier mon image png pour ajouter un remplissage transparent de 10 pixels, et cela fonctionne bien, sans codage du tout!
Créez une classe UITextField personnalisée et utilisez-la à la place de UITextField. Remplacer - (CGRect) textRectForBounds: (CGRect) bornes pour définir le rect dont vous avez besoin
Exemple
- (CGRect)textRectForBounds:(CGRect)bounds{
CGRect textRect = [super textRectForBounds:bounds];
textRect.Origin.x += 10;
textRect.size.width -= 10;
return textRect;
}
...
textField.rightView = UIImageView(image: ...)
textField.rightView?.contentMode = .top
textField.rightView?.bounds.size.height += 10
textField.rightViewMode = .always
...
Une astuce: Ajoutez un UIView contenant UIImageView à UITextField en tant que rightView. La taille de cet UIView doit être plus grande. Placez maintenant UIImageView à gauche de celui-ci. Donc, il y aura un rembourrage de l'espace de droite.
// Add a UIImageView to UIView and now this UIView to UITextField - txtFieldDate
UIView *viewRightIntxtFieldDate = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 30)];
// (Height of UITextField is 30px so height of viewRightIntxtFieldDate = 30px)
UIImageView *imgViewCalendar = [[UIImageView alloc] initWithFrame:CGRectMake(0, 10, 10, 10)];
[imgViewCalendar setImage:[UIImage imageNamed:@"calendar_icon.png"]];
[viewRightIntxtFieldDate addSubview:imgViewCalendar];
txtFieldDate.rightViewMode = UITextFieldViewModeAlways;
txtFieldDate.rightView = viewRightIntxtFieldDate;
J'ai créé une méthode personnalisée dans ma classe ViewController, comme illustré ci-dessous:
- (void) modifyTextField:(UITextField *)textField
{
// Prepare the imageView with the required image
uint padding = 10;//padding for iOS7
UIImageView * iconImageView = [[UIImageView alloc] initWithImage:iconImage];
iconImageView.frame = CGRectMake(0 + padding, 0, 16, 16);
// Set the imageView to the left of the given text field.
textField.leftView = iconImageView;
textField.leftViewMode = UITextFieldViewModeAlways;
}
Maintenant, je peux appeler cette méthode à l'intérieur (viewDidLoad
method) et envoyer n'importe lequel de mes TextFields
à cette méthode et y ajouter un rembourrage à droite et à 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! J'espère que cela fonctionne toujours sur iOS 8 et 9 aussi!
Je sais que l'ajout de trop de vues peut rendre cet objet un peu plus lourd à charger. Mais, préoccupé par la difficulté des autres solutions, je me suis retrouvé plus enclin à utiliser cette méthode et plus souple à l’utiliser. ;)
J'espère que cette réponse sera utile ou utile pour trouver une autre solution à quelqu'un d'autre.
À votre santé!
Approche simple:
textField.rightViewMode = .always
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 25, height: 15))
textField.contentMode = .scaleAspectFit
imageView = UIImage(named: "imageName")
textField.rightView = imageView
Remarque: La hauteur doit être inférieure à la largeur pour permettre le remplissage horizontal.
pour Swift2, j'utilise
...
self.mSearchTextField.leftViewMode = UITextFieldViewMode.Always
let searchImg = UIImageView(image: UIImage(named: "search.png"))
let size = self.mSearchTextField.frame.height
searchImg.frame = CGRectMake(0, 0, size,size)
searchImg.contentMode = UIViewContentMode.ScaleAspectFit
self.mSearchTextField.leftView = searchImg
...
Le moyen le plus simple est de changer le champ de texte comme RoundRect au lieu de Custom et de voir la magie. :)
Voici une solution:
UIView *paddingTxtfieldView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 42)]; // what ever you want
txtfield.leftView = paddingTxtfieldView;
txtfield.leftViewMode = UITextFieldViewModeAlways;
Si vous utilisez un UIImageView en tant que leftView, vous devez utiliser ce code:
Attention: n'utilisez pas à l'intérieur viewWillAppear ou viewDidAppear
-(UIView*)paddingViewWithImage:(UIImageView*)imageView andPadding:(float)padding
{
float height = CGRectGetHeight(imageView.frame);
float width = CGRectGetWidth(imageView.frame) + padding;
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
[paddingView addSubview:imageView];
return paddingView;
}
merci les gars pour vos réponses, à ma grande surprise, aucun d’entre eux n’a vraiment adapté la bonne image à mon champ de texte tout en fournissant le rembourrage nécessaire. alors j'ai pensé à utiliser le mode AspectFill et des miracles se sont produits. pour les futurs demandeurs, voici ce que j'ai utilisé:
UIImageView *emailRightView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 35, 35)];
emailRightView.contentMode = UIViewContentModeScaleAspectFill;
emailRightView.image = [UIImage imageNamed:@"icon_email.png"];
emailTextfield.rightViewMode = UITextFieldViewModeAlways;
emailTextfield.rightView = emailRightView;
le 35 dans le cadre de mon imageview représente la hauteur de mon emailTextfield, n'hésitez pas à l'adapter à vos besoins.
L'exemple ci-dessous concerne l'ajout d'un remplissage horizontal à une vue gauche qui se trouve être une icône. Vous pouvez utiliser l'approche similaire pour ajouter un remplissage à n'importe quel UIView
que vous souhaitez utiliser comme vue gauche du champ de texte.
Inside UITextField
subclass:
static CGFloat const kLeftViewHorizontalPadding = 10.0f;
@implementation TextFieldWithLeftIcon
{
UIImage *_image;
UIImageView *_imageView;
}
- (instancetype)initWithFrame:(CGRect)frame image:(UIImage *)image
{
self = [super initWithFrame:frame];
if (self) {
if (image) {
_image = image;
_imageView = [[UIImageView alloc] initWithImage:image];
_imageView.contentMode = UIViewContentModeCenter;
self.leftViewMode = UITextFieldViewModeAlways;
self.leftView = _imageView;
}
}
return self;
}
#pragma mark - Layout
- (CGRect)leftViewRectForBounds:(CGRect)bounds
{
CGFloat widthWithPadding = _image.size.width + kLeftViewHorizontalPadding * 2.0f;
return CGRectMake(0, 0, widthWithPadding, CGRectGetHeight(bounds));
}
Bien que nous soyons un sous-groupe UITextField
ici, je crois que cette approche est la plus propre.
- (CGRect)rightViewRectForBounds:(CGRect)bounds
{
return CGRectMake(bounds.size.width - 40, 0, 40, bounds.size.height);
}
Au lieu de manipuler imageView ou image, nous pouvons remplacer une méthode fournie par Apple pour rightView.
class CustomTextField : UITextField {
override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
let offset = 5
let width = 20
let height = width
let x = Int(bounds.width) - width - offset
let y = offset
let rightViewBounds = CGRect(x: x, y: y, width: width, height: height)
return rightViewBounds
}}
de la même manière, nous pouvons remplacer ci-dessous func pour la vue de gauche.
override func leftViewRect(forBounds bounds: CGRect) -> CGRect {
/*return as per requirement*/
}