我想插入一个UITextField的文本。
这可能吗?
我想插入一个UITextField的文本。
这可能吗?
当前回答
在从UITextField派生的类中,至少重写以下两个方法:
- (CGRect)textRectForBounds:(CGRect)bounds;
- (CGRect)editingRectForBounds:(CGRect)bounds;
如果你没有额外的内容,它可能就像这样简单:
return CGRectInset(bounds , 10, 10);
UITextField提供了几个可以覆盖的定位方法。
其他回答
为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
我通常尽量避免子类化,但如果你已经:
// add a property
@property (nonatomic) UIEdgeInsets edgeInsets;
// and override:
- (CGRect)textRectForBounds:(CGRect)bounds
{
return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}
- (CGRect)editingRectForBounds:(CGRect)bounds
{
return [super editingRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}
Swift 5版本的克里斯托弗的答案与额外的用法示例
import UIKit
private class InsetTextField: UITextField {
var insets: UIEdgeInsets
init(insets: UIEdgeInsets) {
self.insets = insets
super.init(frame: .zero)
}
required init(coder aDecoder: NSCoder) {
fatalError("not intended for use from a NIB")
}
// placeholder position
override func textRect(forBounds bounds: CGRect) -> CGRect {
return super.textRect(forBounds: bounds.inset(by: insets))
}
// text position
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return super.editingRect(forBounds: bounds.inset(by: insets))
}
}
extension UITextField {
class func textFieldWithInsets(insets: UIEdgeInsets) -> UITextField {
return InsetTextField(insets: insets)
}
}
用法:-
class ViewController: UIViewController {
private let passwordTextField: UITextField = {
let textField = UITextField.textFieldWithInsets(insets: UIEdgeInsets(top: 10, left: 15, bottom: 10, right: 15))
// ---
return textField
}()
}
This is not as short as the other examples, but takes an entirely different approach to solving this problem. Note, the caret will still begin flush to the left edge but the text will be properly indented when typed/displayed. This works without subclassing if your looking for just a left margin and you are already using UITextFieldDelegate for your text fields. You need to set both the default text attributes and the typing attributes. You set the default text attributes when you create the text field. The typing attributes you need to set in the delegate. If you are also using a placeholder you will want to set that to the same margin as well. Putting it altogether you get something like this.
首先在UITextField类上创建一个类别。
// UITextField+TextAttributes.h
#import <UIKit/UIKit.h>
@interface UITextField (TextAttributes)
- (void)setIndent:(CGFloat)indent;
@end
// UITextField+TextAttributes.m
#import "UITextField+TextAttributes.h"
@implementation UITextField (TextAttributes)
- (void)setTextAttributes:(NSDictionary*)textAttributes indent:(CGFloat)indent
{
if (!textAttributes) return;
NSMutableParagraphStyle *paragraphStyle = [textAttributes objectForKey:NSParagraphStyleAttributeName];
paragraphStyle.firstLineHeadIndent = indent;
paragraphStyle.headIndent = indent;
}
- (void)setIndent:(CGFloat)indent
{
[self setTextAttributes:self.defaultTextAttributes indent:indent];
[self setTextAttributes:self.typingAttributes indent:indent];
}
@end
然后,如果您使用放置占位符,请确保使用带有属性的占位符设置相同的缩进。创建一个具有正确属性的默认属性字典,如下所示:
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.firstLineHeadIndent = 7;
paragraphStyle.headIndent = 7;
NSDictionary *placeholderAttributes = [NSDictionary dictionaryWithObjectsAndKeys: paragraphStyle, NSParagraphStyleAttributeName, nil];
然后,导入上述类别,每当你创建一个文本字段设置默认缩进,委托和使用默认占位符属性上面定义。例如:
UITextField *textField = [[UITextField alloc] init];
textField.indent = 7;
textField.delegate = self;
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Placeholder Text" attributes:placeholderAttributes];
最后,在委托中,实现textFieldDidBeginEditing方法,就像这样:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
textField.indent = 7;
}
如果你想改变TOP和LEFT缩进只有这样
//占位符
- (CGRect)textRectForBounds:(CGRect)bounds {
CGRect frame = bounds;
frame.origin.y = 3;
frame.origin.x = 5;
bounds = frame;
return CGRectInset( bounds , 0 , 0 );
}
//文本位置
- (CGRect)editingRectForBounds:(CGRect)bounds {
CGRect frame = bounds;
frame.origin.y = 3;
frame.origin.x = 5;
bounds = frame;
return CGRectInset( bounds , 0 , 0 );
}