使用UITextBorderStyleNone设置UITextField的内边距

418

我想为我的UITextFields使用自定义背景。虽然这样可以工作得很好,但问题是我必须使用UITextBorderStyleNone才能使其看起来漂亮。这将强制文本紧贴左侧且没有填充。

我是否可以手动设置填充,以使其外观类似于UITextBorderStyleRoundedRect,而不使用自定义背景图像?

32个回答

3

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

2

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

2

您可以使用分类,将左右内边距设置为填充。

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;


2

这里是一段用Swift编写的代码,用于在UITextfield中添加填充(padding)

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

并使用电话进行呼叫
self.txtPaddingVw(txtPin)

2

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 设置了右侧填充。

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

该方法可以通过[self addPaddingToAllTextFields:[self view]]调用。 - Kishor Kundan
由于第二个 if 块中未定义 textfieldarray,因此我使用了这个片段(感谢!),在将第二个 if 的内容替换为 for(id subSubView in [view subviews]){[self addPaddingToAllTextFields:subSubView];} 后成功运行。 - adamup

1

Brody的解决方案对我非常有效。我不得不在一个文本字段上添加侧视图并添加额外的填充。因此,通过将自定义UIEdgeInsets属性实现到UITextField子类中,我成功地完成了任务。我将在所有项目中使用这个新的子类。


1
到目前为止我找到的最佳解决方案是创建一个分类。这样我就可以给左右各添加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”只是用来消除烦人的警告信息的。

类别中的方法重载的问题在于,它会被AppCode标记为未使用,而事实上它确实是未使用的。这是一个好主意,但不太安全,因为当您运行“优化导入”时,它很容易被删除(对Xcode用户来说没有问题,但我们都知道代码中心功能的局限性)。 - Sebastian Wramba
1
这是一个简单的糟心类别,它会为应用程序中的所有文本字段应用填充。 - pronebird
@Andy 不,它只适用于您导入它时,您需要创建一个类UITextField+Padding并在视图控制器或具有填充文本字段的类中导入它。 - Mongi Zaidi
@MongiZaidi:你是错的,它被链接到可执行文件中,无论是否被导入都是无关紧要的。 - Zsolt Szatmari

0

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接