Definir preenchimento para UITextField com UITextBorderStyleNone

Eu queria usar um fundo personalizado para meus UITextFields . Isso funciona bem, exceto pelo fato de que eu tenho que usar UITextBorderStyleNone para fazer com que pareça bonito. Isso força o texto a ficar à esquerda sem qualquer preenchimento.

Posso definir um preenchimento manualmente para que pareça semelhante a UITextBorderStyleRoundedRect exceto para usar minha imagem de plano de fundo personalizada?

Eu encontrei um pequeno hack para definir o preenchimento da esquerda para essa situação exata.

Basicamente, você define a propriedade leftView do UITextField como uma exibição vazia do tamanho do preenchimento desejado:

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

Caiu como uma luva para mim!

No Swift 3 , isso pode ser feito fazendo

 let paddingView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 5, height: 20)) textField.leftView = paddingView textField.leftViewMode = .always 

Eu criei esta implementação de categoria e adicionei-a ao topo do arquivo .m .

 @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 

Baseado fora do link Piotr Blasiak fornecido. Parecia mais simples do que criar uma nova subclass, e também mais simples, adicionando o UIView adicional. Ainda assim, parece que algo está faltando para não conseguir controlar o preenchimento dentro de um campo de texto.

Solução Swift 2:

 import UIKit class CustomTextField: UITextField { required init?(coder aDecoder: NSCoder){ super.init(coder: aDecoder) } override func textRectForBounds(bounds: CGRect) -> CGRect { return CGRectMake(bounds.origin.x + 10, bounds.origin.y + 8, bounds.size.width - 20, bounds.size.height - 16); } override func editingRectForBounds(bounds: CGRect) -> CGRect { return self.textRectForBounds(bounds); } } 

Uma versão do Swift 3 para Xcode> 6, onde você pode editar o valor inserido no 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) } } 

insira a descrição da imagem aqui

Uma boa abordagem para adicionar preenchimento ao UITextField é criar uma subclass e adicionar uma propriedade edgeInsets. Em seguida, você configura o edgeInsets e o UITextField será desenhado de acordo. Isso também funcionará corretamente com um conjunto personalizado leftView ou rightView.

OSTextField.h

 #import  @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 

Editar: ainda funciona no iOS 11.3.1

No iOS 6 myTextField.leftView = paddingView; está causando problema

Isso resolve o problema

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

Para o campo de texto alinhado à direita, use CATransform3DMakeTranslation(-5, 0, 0) como mencionado por latenitecoder em comentários

Apenas subclass UITextField assim:

 @implementation DFTextField - (CGRect)textRectForBounds:(CGRect)bounds { return CGRectInset(bounds, 10.0f, 0); } - (CGRect)editingRectForBounds:(CGRect)bounds { return [self textRectForBounds:bounds]; } @end 

Isso adiciona preenchimento horizontal de 10 pontos de cada lado.

Código C Objetivo

MyTextField.h

 #import  @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 

insira a descrição da imagem aqui

Com base na resposta do Evil Trout, você pode querer criar uma categoria para facilitar o uso em vários aplicativos.

Arquivo de header:

 @interface UITextField (PaddingText) -(void) setLeftPadding:(int) paddingValue; -(void) setRightPadding:(int) paddingValue; @end 

Arquivo de implementação:

 #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 

Exemplo de uso

 #import "UITextField+PaddingText.h" [self.YourTextField setLeftPadding:20.0f]; 

Espero que ajude vocês

Felicidades

  1. Criar um campo de texto personalizado

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. Definir sua class de campo de texto é PaddingTextField e personalizar seu preenchimento como você deseja insira a descrição da imagem aqui insira a descrição da imagem aqui

  2. Aproveite

final

Versão rápida:

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

Para que você possa atribuir valor no IB

Configuração IBInspectable representada no Interface Builder

Você não pode definir preenchimento. Em vez disso, tenha uma UIView que tenha sua imagem de fundo e o UITextField dentro dela. Defina a largura UITextField como UIViewWidth-(paddingSize x 2) e a altura de forma semelhante e, em seguida, defina-a no ponto paddingSize,paddingSize .

Apenas subclass UITextField assim ( versão 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) } } 

Isso adiciona acolchoamento horizontal de 25,0 pontos de cada lado.

Eu fui baseado na solução do Nate, mas depois achei que isso causa problemas quando você usa as propriedades leftView / rightView, então é melhor ajustar a implementação do super, porque ele levará a visão da esquerda / direita em consideração.

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

Veja como conseguir isso no 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 } } 

Recurso

Versão Swift 2.0:

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

Estas sugestões são ótimas para aqueles que estão programaticamente criando uma interface.

Mas existem duas maneiras fáceis e fáceis para aqueles de nós que usam o construtor de interfaces Xcode:

  • mais fácil: coloque um UIImageView atrás de um campo de texto

  • mais fácil: mude o estilo de borda no seu para o quadrado preto simples (segundo da opção esquerda), depois adicione sua imagem como uma imagem de fundo. A imagem tem precedência sobre o quadrado, portanto, você ainda obtém o preenchimento necessário para um plano de fundo de imagem normal, sem que o quadrado realmente esteja sendo desenhado.

EDIT: você também pode usar a esfera preta (terceiro da opção à esquerda ao selecionar o UITextBox em IB), ele não funciona com o estilo “esfera gráfica” da extrema direita.

A melhor maneira de fazer isso é simplesmente criar uma class usando a subclass de UITextField e o arquivo .m

  #import "CustomTextField.h" #import  @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; } 

Ao fazer isso, vá para o storyboard ou o xib e clique no inspetor de identidade e substitua UITextfield por sua própria opção “CustomTextField” na class.

Nota: Se você simplesmente fornecer um preenchimento com layout automático para o campo de texto, seu aplicativo não será executado e mostrará apenas a canvas em branco.

Versão atualizada para o 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) } } 

Solução 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) } } 

Definir preenchimento para UITextField com UITextBorderStyleNone: Swift

Baseado na resposta mais votada do @Evil Trout eu criei um método personalizado na minha class ViewController, como mostrado abaixo:

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

Agora eu posso chamar esse método dentro (método viewDidLoad) e enviar qualquer um dos meus TextFields para esse método e adicionar preenchimento para direita e esquerda e dar colors de texto e plano de fundo, escrevendo apenas uma linha de código, da seguinte maneira:

 [self modifyTextField:self.firstNameTxtFld]; 

Isso funcionou perfeitamente no iOS 7! Eu sei que adicionar muito Views pode fazer com que esta seja uma class um pouco mais pesada para ser carregada. Mas quando me preocupei com a dificuldade em outras soluções, me vi mais inclinado a esse método e mais flexível ao usar dessa maneira. 😉

Obrigado pelo Hack “Mal Trout”! (arco)

Eu pensei que deveria atualizar o snippet de código desta resposta com o Swift:

Como o Swift nos permite escrever extensões para as classs existentes, vamos escrevê-lo dessa maneira.

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

Uso:

 self.firstNameTxtFld.addPaddingToTextField() 

Espero que isso seja útil para alguém lá fora!
Felicidades!

A resposta do @Evil trout é ótima. Eu tenho usado essa abordagem por um bom tempo agora. A única coisa que falta é “lidar com vários campos de texto”. Eu tentei outras abordagens, mas parece não funcionar.

Subclassing UITextField apenas para adicionar um preenchimento não fazia qualquer sentido para mim. Então, eu iterei sobre todos os UITextFields para adicionar o preenchimento.

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

A solução de Brody funcionou perfeita para mim. Eu tive que adicionar vistas laterais em um campo de texto e adicionar preenchimento adicional. Então, implementando a propriedade UIEdgeInsets personalizada em uma subclass UITextField, consegui atingir a tarefa. Eu vou usar essa nova subclass em todos os meus projetos.

 textField.layer.borderWidth = 3; 

irá adicionar borda, que funcionou como preenchimento para mim.

Aqui está um código Swift para dar preenchimento em UITextfield

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

e ligue usando

 self.txtPaddingVw(txtPin) 

Outra consideração é que, se você tiver mais de um UITextField onde você está adicionando preenchimento, é criar um UIView separado para cada campo de texto – porque eles não podem ser compartilhados.

Por que não String Atribuído!? !, este é um dos resources de bênção do 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}]; 

A resposta de Nate Flink é a minha favorita, mas não se esqueça das visualizações direita / esquerda. Por exemplo, para a subclass UITextField :

 override func rightViewRectForBounds(bounds: CGRect) -> CGRect { let rightViewBounds = super.rightViewRectForBounds(bounds) return CGRectMake(CGRectGetMinX(rightViewBounds) - 10, CGRectGetMinY(rightViewBounds), CGRectGetWidth(rightViewBounds), CGRectGetHeight(rightViewBounds)) } 

Acima de código set padding direito para rightView de UITextField .

você pode usar categoria. conjunto de preenchimento para esquerda e direita

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

você pode definir o preenchimento como este self.phoneNumTF.paddingValue = 10.f; ou self.phoneNumTF.leftPadding = 10.f;

Versão 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) } } 

Se alguém estiver procurando pela versão Swift 4.0 , a extensão abaixo será trabalho. Tem o preenchimento Left e Right para o UITextField .

Tenha em mente que se você quiser habilitar o Clear Button no mesmo UITextField então você precisa manter Right Padding branco.

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