【问题标题】:Indent the text in a UITextField缩进 UITextField 中的文本
【发布时间】:2011-11-25 19:26:37
【问题描述】:

我的问题和标题一样简单,但这里还有一点:

我有一个 UITextField,我在上面设置了背景图像。问题是文本紧贴它的边缘,这也是图像的边缘。我希望我的文本字段看起来像 Apple 的,在背景图像和文本开始位置之间有一点水平空间。

【问题讨论】:

  • 你的意思是设置文本的插图吗?那就试试这个问题:stackoverflow.com/questions/2694411/text-inset-for-uitextfield
  • 您可以添加带有图像的 UIImageView,在其顶部添加文本字段并相应地设置文本字段的宽度...这是最简单的解决方案...
  • @lukya 除非他希望文本字段的可点击区域包含图像部分,在这种情况下,您的方法将需要额外的手势识别器和一些代码才能使其正常工作。

标签: iphone objective-c ios cocoa-touch uitextfield


【解决方案1】:

这是我在不做任何子类的情况下找到的最快方法:

UIView *spacerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
[textfield setLeftViewMode:UITextFieldViewModeAlways];
[textfield setLeftView:spacerView];

在斯威夫特中:

let spacerView = UIView(frame:CGRect(x:0, y:0, width:10, height:10))
textField.leftViewMode = UITextFieldViewMode.Always
textField.leftView = spacerView

【讨论】:

  • 这比子类化更干净,并且可以正确处理清除按钮。希望我能给 +2。
  • 我同意,如果可以的话 +2。一旦我在投票率很高的答案中读到“子类”,我就在内心抱怨,因为开始用绘图方法愚弄总是更难,更容易出错
  • 很好的解决方案,刚刚翻译成 Swift:var spacerView = UIView(frame:CGRect(x:0, y:0, width:10, height:10)); textfield.leftViewMode = UITextFieldViewMode.Always textfield.leftView = spacerView
  • @jsiodtb 我尝试在 Swift 中使用它,但它阻止了我的 segue 被执行。知道为什么吗?我viewDidLoad() 中调用它。它也不适用于viewWillAppear()
  • @Arcrammer 您不允许使用相同的视图作为两次填充(这会导致您描述的错误)
【解决方案2】:

您必须继承和覆盖 textRectForBounds: 并编辑RectForBounds:。这是一个带有自定义背景和垂直和水平填充的 UITextfield 子类:

@interface MyUITextField : UITextField 
@property (nonatomic, assign) float verticalPadding;
@property (nonatomic, assign) float horizontalPadding;
@end

#import "MyUITextField.h"
@implementation MyUITextField
@synthesize horizontalPadding, verticalPadding;
- (CGRect)textRectForBounds:(CGRect)bounds {
    return CGRectMake(bounds.origin.x + horizontalPadding, bounds.origin.y + verticalPadding, bounds.size.width - horizontalPadding*2, bounds.size.height - verticalPadding*2);
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}
@end

用法:

UIImage *bg = [UIImage imageNamed:@"textfield.png"];
CGRect rect = CGRectMake(0, 0, bg.size.width, bg.size.height);
MyUITextField *textfield = [[[MyUITextField alloc] initWithFrame:rect] autorelease];
textfield.verticalPadding = 10; 
textfield.horizontalPadding = 10;
[textfield setBackground:bg];
[textfield setBorderStyle:UITextBorderStyleNone];
[self.view addSubview:textfield];

【讨论】:

  • 这是一个很好的解决方案,但是当它可见时它不考虑清除按钮。不过 +1。
  • 很棒的解决方案!不敢相信 Apple 不允许您为 UITextField 设置插图!
  • @RPM 由于 iOS 6.0 UITextView 有一个属性文本属性,所以你可以设置 NSAttributedString 属性 NSMutableParagraphStyle + firstLineHeadIndent (和 tailIndent 清除按钮)。但是,是的,它需要 iOS 6。
  • 无论出于何种原因,NSParagraphStyle 中的 firstLineHeadIndent 似乎对 iOS 6 中 UITextField 中文本的显示方式没有影响。
【解决方案3】:

向 UITextField 添加填充的一个好方法是继承 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 = UIEdgeInsetsMake(0, 0, 0, 0);
    }
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if(self){
        self.edgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
    }
    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

【讨论】:

  • 良好而干净的方法。请注意阅读此评论的其他人:使用 spaceView 并将 leftView 分配给文本视图是一种诱惑,但是当您有许多文本字段时,您是否会通过将 spaceViews 添加到所有 textField 来复制代码?可能没有,所以如果您有很多文本字段,请使用此子类化。
  • 简洁的解决方案。 +1 使用 UIEdgeInsets 这绝对是手头任务的合适工具!
  • 这行得通,如果那些 UITextFields 使用自动布局,我找到了崩溃的公认答案。
  • 比 IMO 投票最多的答案要干净得多。干得好。
  • 基于现有控件创建自定义控件的一般概念的出色方法。我以此为基础将所有自定义 Swift 控件移植到 Objective-C,现在 IB 在加载 Designables 时不再崩溃。 (我应该补充一点,我的控件设置了 IB_DESIGNABLE)
【解决方案4】:

我把它变成了一个很好的小扩展,可以在 Storyboards 中使用:

public extension UITextField {
    @IBInspectable public var leftSpacer:CGFloat {
        get {
            return leftView?.frame.size.width ?? 0
        } set {
            leftViewMode = .Always
            leftView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
        }
    }
}

【讨论】:

  • 这个完美。如果你将它与@IBDesignable 一起使用,你可以在故事板中看到它
【解决方案5】:

我的 2 美分:

class PaddedTextField : UITextField {
    var insets = UIEdgeInsets.zero
    var verticalPadding:CGFloat = 0
    var horizontalPadding:CGFloat = 0

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.origin.x + insets.left, y: bounds.origin.y + insets.top, width: bounds.size.width - (insets.left + insets.right), height: bounds.size.height - (insets.top + insets.bottom));
    }

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

【讨论】:

    【解决方案6】:

    我建议将您的UITextField 转换为UITextView 并设置contentInset。例如缩进 10 个空格:

    textview.contentInset=UIEdgeInsetsMake(0, 10, 0, 0);
    

    【讨论】:

    • 这实际上是一个很好的解决方案,不知道为什么它被否决了。
    • @Jeremie 这是因为这不能回答问题。 UITextField 和 UITextView 的行为不同,您必须大幅修改文本视图以使其行为类似于文本字段
    【解决方案7】:

    有时 textField 的 leftView 是苹果的放大镜图像。 如果是这样,您可以像这样设置缩进:

        UIView *leftView = textField.leftView;
        if (leftView && [leftView isKindOfClass:[UIImageView class]]) {
            leftView.contentMode = UIViewContentModeCenter;
            leftView.width = 20.0f;  //the space you want indented.
        }
    

    【讨论】:

      【解决方案8】:

      如果您不想创建@IBOutlet,可以简单地继承(在 Swift 中回答):

      class PaddedTextField: UITextField {
      
        override func awakeFromNib() {
            super.awakeFromNib()
      
            let spacerView = UIView(frame:CGRect(x: 0, y: 0, width: 10, height: 10))
            leftViewMode = .always
            leftView = spacerView
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-20
        • 2015-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多