使用UITextBorderStyleNone为UITextField设置填充

我想为我的UITextFields使用自定义的背景。 这工作正常,除了我不得不使用UITextBorderStyleNone使它看起来漂亮。 这迫使文本粘在左边没有任何填充。

我可以手动设置填充,使其看起来类似于UITextBorderStyleRoundedRect除了使用我的自定义背景图像吗?

我发现一个整洁的小黑客为这个确切的情况设置左边的填充。

基本上,您将UITextField的leftView属性设置为所需填充大小的空白视图:

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

为我工作就像一个魅力!

我创build了这个类别的实现,并将其添加到.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 

基于Piotr Blasiak提供的链接。 这似乎更简单,然后创build一个全新的子类,也更简单,然后添加额外的UIView 。 不过,似乎有些东西是不能够控制文本字段内的填充。

Swift 2解决scheme:

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

Xcode> 6的Swift 3版本,您可以在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) } } 

在这里输入图像描述

将填充添加到UITextField的一个好方法是inheritance并添加edgeInsets属性。 然后设置edgeInsets,并相应地绘制UITextField。 这也将正确使用自定义leftView或rightView设置。

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 

在iOS 6中myTextField.leftView = paddingView; 导致问题

这解决了这个问题

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

只需要像这样子类UITextField:

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

这增加了任何一方10点的水平填充。

根据Evil Trout的回答,您可能想要创build一个类别,以便在多个应用程序中使用它。

头文件:

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

实施文件:

 #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 

用法示例

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

希望它可以帮助你们

干杯

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

在这里输入图像描述

  1. 创build一个文本字段自定义

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. 设置您的文本字段类是PaddingTextField和自定义您的填充,只要你想 在这里输入图像描述 在这里输入图像描述

  2. 好好享受

最后

你不能设置填充。 而是有一个UIView有你的背景图像和UITextField里面。 将UITextField宽度设置为UIViewWidth-(paddingSize x 2)和高度,然后将其设置为paddingSize,paddingSize

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

这样你可以在IB中分配值

Interface Builder中表示的IBInspectable设置

只是子类UITextField像这样( 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) } } 

这增加了25.0点的水平填充。

我是基于Nate的解决scheme,但后来我发现这会导致您使用leftView / rightView属性时出现问题,所以它更好地调整超级的实现,因为它会考虑到左/右视图。

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

以下是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 } } 

资源

Swift 2.0版本:

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

^这些build议对于以编程方式创build接口的人来说是非常好的。

但是对于我们这些使用Xcode接口构build器的人来说,有两种懒惰的简单方法:

  • 更简单:将UIImageView放在文本字段后面

  • 最简单:将您的边框样式更改为简单的黑色方块(左边第二个选项),然后将图像添加为背景图像。 图像优先于正方形,所以仍然可以获得正常图像背景所需的填充,而不需要实际绘制正方形。

编辑:你也可以使用黑色球体(在IB中selectUITextBox时左边的第三个选项),它不适用于最右边的“graphics球体”风格。

最好的方法是使用UITextField的子类和.m文件创build一个类

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

通过这样做去你的故事板或XIB,并点击身份检查,并用类选项中自己的“CustomTextField”replaceUITextfield。

注意:如果你只是给自动布局填充文本字段,那么你的应用程序将不会运行,只显示空白屏幕。

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

Swift 3解决scheme

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

使用UITextBorderStyleNone设置UITextField的填充:Swift

根据@Evil鳟鱼的投票最多的答案我创build了一个自定义的方法在我的ViewController类,如下图所示:

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

现在,我可以调用里面的方法(viewDidLoad方法),并发送我的任何TextFields到该方法,并添加左右两边的填充,并通过只写一行代码给文本和背景颜色,如下所示:

 [self modifyTextField:self.firstNameTxtFld]; 

这在iOS 7上完美工作! 我知道添加太多的视图可能会使这个有点重的类加载。 但是,当担心其他解决scheme中的困难时,我发现自己更偏向于这种方法,并且使用这种方法更灵活。 ;)

感谢黑客“邪恶的鳟鱼”! (弓)

我以为我应该用Swift更新这个答案的代码片段:

既然Swift允许我们为现有的类编写扩展,那就让我们这样写。

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

用法:

 self.firstNameTxtFld.addPaddingToTextField() 

希望这将有助于其他人在那里!
干杯!

@Evil鳟鱼的答案是伟大的。 我一直在使用这种方法已经有一段时间了。 它唯一缺乏的是“处理大量文本字段”。 我尝试了其他方法,但似乎没有工作。

为了添加填充而inheritanceUITextField对我来说没有任何意义。 所以,我遍历所有的UITextFields添加填充。

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

布罗迪的解决scheme对我来说非常合适。 我不得不在文本框上添加侧视图并添加额外的填充。 所以通过实现自定义UIEdgeInsets属性到一个UITextField子类,我已经设法完成任务。 我将在我所有的项目中使用这个新的子类。

 textField.layer.borderWidth = 3; 

将添加边框,为我填充工作。

这是一个在UITextfield中填充的Swift代码

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

并打电话使用

 self.txtPaddingVw(txtPin) 

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

另一个考虑是,如果你有多个UITextField你要添加填充,是为每个文本字段创build一个单独的UIView – 因为它们不能共享。

为什么不是归属string!!,这是IOS 6.0的祝福function之一:)

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

Nate Flink的回答是我的最爱,但不要忘记右/左视图。 例如对于UITextField子类:

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

上面的代码设置了正确的填充rightViewUITextField

你可以使用类别。 设置填充左右

的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 

你可以像这样设置填充 self.phoneNumTF.paddingValue = 10.f; 或self.phoneNumTF.leftPadding = 10.f;

我发现迄今为止最好的解决scheme是一个类别。 这就是我如何添加5点填充左侧和右侧:

 @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 

#pragma只是为了消除恼人的警告