提问



我想为我的UITextFields使用自定义背景。除了我必须使用UITextBorderStyleNone使它看起来很漂亮之外,这个工作正常。这会强制文本粘在左边而不会有任何填充。


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

最佳参考


我找到了一个整洁的小黑客为这种确切的情况设置左边填充。


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


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


对我来说就像一个魅力!


Swift 3 中,可以通过这样做来完成


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

其它参考1


我创建了这个类别实现并将其添加到.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提供的链接。它似乎比创建一个全新的子类更简单,也更简单,然后添加额外的UIView。但是,似乎缺少一些东西,因为无法控制文本字段内的填充。


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

其它参考2


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

}




其它参考3


向UITextField添加填充的一种好方法是子类化并添加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

其它参考4


编辑:仍适用于iOS 11.3.1


在iOS 6中myTextField.leftView = paddingView;引起了问题


这解决了这个问题


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


对于右对齐文本字段,请在评论中使用 latenitecoder 提及CATransform3DMakeTranslation(-5, 0, 0)

其它参考5


只需将UITextField子类化为:


@implementation DFTextField


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

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


@end


这会在任一侧增加10个点的水平填充。

其它参考6


基于Evil Trout的回答,您可能想要创建一个类别,以便更容易在多个应用程序中使用。


头文件:


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


希望它可以帮助你们


干杯

其它参考7


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




其它参考8



  1. 创建文本字段自定义




  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. 设置textfield类是PaddingTextField并根据需要自定义填充

    [56] [57]

  2. 享受它



[58]

其它参考9


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

其它参考10


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中分配价值了




其它参考11


只需像这样( Swift版本)继承 UITextField :


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 点的水平填充。

其它参考12


我基于Nate的解决方案,但后来我发现当你使用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];
}

其它参考13


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


资源[59]

其它参考14


Swift 2.0版本:


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

其它参考15


^这些建议非常适合以编程方式创建界面的人。


但对于我们这些使用Xcode界面构建器的人来说,有两种轻松的方式:



  • 更容易:将UIImageView放在文本字段后面

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



编辑:您也可以使用黑色球体(在IB中选择UITextBox时左侧第三个选项),它不适用于最右侧的图形球体样式。

其它参考16


执行此操作的最佳方法是使用UITextField的子类和.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;

 }


通过执行此操作转到storyboard或xib并单击身份检查器,并在类选项中将UITextfield替换为您自己的CustomTextField。


注意:如果您只是为textfield提供自动布局的填充,那么您的应用程序将无法运行并仅显示空白屏幕。

其它参考17


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

其它参考18


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

其它参考19


使用UITextBorderStyleNone设置UITextField的填充:Swift



基于@Evil Trout的最多投票答案,我在我的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上完美运行!
我知道添加太多的视图可能会使这个类加载更重一些。但是当担心其他解决方案的难度时,我发现自己对这种方法更偏向于使用这种方式更灵活。 ;)


感谢HackEvil Trout! (弓)


我以为我应该用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()


希望这对那里的其他人有所帮助!

干杯!

其它参考20


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


对UITextField进行子类化只是为了添加填充对我没有任何意义。所以,我迭代所有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**];
        }
    }
}

其它参考21


Brody的解决方案对我来说非常合适。我必须在文本字段上添加侧视图并添加额外的填充。因此,通过将自定义UIEdgeInsets属性实现到UITextField子类,我已设法完成任务。我将使用此我所有项目中的新子类。

其它参考22


textField.layer.borderWidth = 3;


将添加边框,这对我来说是一个填充。

其它参考23


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


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


并使用致电


self.txtPaddingVw(txtPin)

其它参考24


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

其它参考25


为什么不归因于字符串!?!,这是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}];

其它参考26


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


上面的代码设置UITextFieldrightView的右边填充。

其它参考27


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


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;

其它参考28


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

其它参考29


到目前为止我找到的最佳解决方案是一个类别。这是我如何向左右添加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只是为了删除恼人的警告