用UITextBorderStyleNone设置UITextField的填充

我想为我的UITextFields使用一个自定义背景。这很好,除了我必须使用UITextBorderStyleNone来使它看起来更漂亮。这将迫使文本保持在左边,没有任何填充。

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

231487 次浏览

你不能设置填充。相反,应该有一个UIView,其中有你的背景图像和UITextField。将UITextField的宽度设置为UIViewWidth-(paddingSize x 2),高度设置为类似的值,然后将其设置为paddingSize,paddingSize

我发现了一个整洁的小hack来设置左侧填充的确切情况。

基本上,你将UITextField的leftView属性设置为你想要的填充大小的空视图:

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

对我来说简直就是魔法!

Swift 3/ Swift 4中,可以这样做

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

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

根据彼得·布拉斯亚克提供的链接。这似乎比创建一个全新的子类更简单,也比添加额外的UIView更简单。不过,似乎缺少了一些东西,无法控制文本字段内的填充。

Swift 4解决方案:

class CustomTextField: UITextField {
struct Constants {
static let sidePadding: CGFloat = 10
static let topPadding: CGFloat = 8
}


override func textRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(
x: bounds.origin.x + Constants.sidePadding,
y: bounds.origin.y + Constants.topPadding,
width: bounds.size.width - Constants.sidePadding * 2,
height: bounds.size.height - Constants.topPadding * 2
)
}


override func editingRect(forBounds bounds: CGRect) -> CGRect {
return self.textRect(forBounds: bounds)
}
}

我发现使用不可编辑的UITextView并设置contentOffset

uiTextView.contentOffset = CGPointMake(8, 7);

另一个需要考虑的问题是,如果你在添加填充的地方有多个UITextField,就要为每个文本字段创建一个单独的UIView——因为它们不能共享。

我是基于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];
}

^这些建议对于那些通过编程方式创建界面的人来说非常有用。

但是对于我们这些使用Xcode界面构建器的人来说,有两个LAZY EASY方法:

  • 更简单:把一个UIImageView放在一个文本字段后面

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

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

为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

为什么不是带属性字符串!?!,这是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}];

只是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的回答很棒。我使用这种方法已经有一段时间了。它唯一缺少的是“处理大量文本字段”。我尝试了其他方法,但似乎不奏效。

子类化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]];
}
}
}

基于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];

希望这对你们有所帮助

干杯

布洛迪的方法对我很有效。我不得不在文本框上添加侧视图,并添加额外的填充。因此,通过实现自定义UIEdgeInsets属性到UITextField子类,我已经成功实现了任务。我将在所有项目中使用这个新子类。

到目前为止,我找到的最佳解决方案是分类。这就是我如何在左右两侧添加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’s只是用来删除恼人的警告

用UITextBorderStyleNone: Swift设置UITextField的填充

基于@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上完美地工作! 我知道添加太多的视图可能会使这个类的加载变得更重一些。但当考虑到其他解决方法的难度时,我发现自己更偏向于这种方法,使用这种方法也更灵活。;) < / p >

谢谢你的“邪恶鳟鱼”!(鞠躬)

我认为我应该用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()
希望这能对其他人有所帮助!
干杯!< / p >

编辑:在iOS 11.3.1中仍然有效

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

这就解决了问题

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

对于右对齐的文本字段,使用CATransform3DMakeTranslation(-5, 0, 0),正如注释中latenitecoder提到的那样

斯威夫特版本:

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中赋值

IBInspectable setting表示在Interface Builder

就像这样子类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点的水平填充。

一个Swift 3版本的Xcode >6,在那里你可以在接口生成器/故事板编辑插入值。

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


}

enter image description here

最好的方法是使用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;


}

通过这样做,去到你的故事板或xib,点击身份检查器,用你自己的“CustomTextField”在类选项替换UITextfield。

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

Objective 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

enter image description here

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

资源

  1. 创建一个文本域Custom

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和自定义你的填充,因为你想要 enter image description hereenter image description here < / p > < / >

  2. 享受它

final

textField.layer.borderWidth = 3;

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

Swift 2.0版本:

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

内特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设置了正确的填充。

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

下面是一个Swift代码,在UITextfield中提供填充

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

调用using

self.txtPaddingVw(txtPin)

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

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

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 f = 10.; 或 < / p > self.phoneNumTF.leftPadding f = 10.;

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

如果有人正在寻找Swift 4.0版本,那么在extension以下是工作。它对UITextFieldLeftRight填充。实际上,它是IBInspectable用于故事板配置。您可以直接从接口构建器/故事板设置该值。这是在Swift 4.0版本和Xcode 9.0的测试代码

请记住,如果你想在同一个UITextField上启用Clear Button,那么你必须保持右填充为空。

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