我想插入一个UITextField的文本。
这可能吗?
我想插入一个UITextField的文本。
这可能吗?
当前回答
我子类化UITextField来处理这个,它支持左,上,右和底部的插入,以及清除按钮的定位。
MRDInsetTextField.h
#import <UIKit/UIKit.h>
@interface MRDInsetTextField : UITextField
@property (nonatomic, assign) CGRect inset;
@end
MRDInsetTextField.m
#import "MRDInsetTextField.h"
@implementation MRDInsetTextField
- (id)init
{
self = [super init];
if (self) {
_inset = CGRectZero;
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
_inset = CGRectZero;
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_inset = CGRectZero;
}
return self;
}
- (void)setInset:(CGRect)inset {
_inset = inset;
[self setNeedsLayout];
}
- (CGRect)getRectForBounds:(CGRect)bounds withInset:(CGRect)inset {
CGRect newRect = CGRectMake(
bounds.origin.x + inset.origin.x,
bounds.origin.y + inset.origin.y,
bounds.origin.x + bounds.size.width - inset.origin.x - inset.size.width,
bounds.origin.y + bounds.size.height - inset.origin.y - inset.size.height
);
return newRect;
}
- (CGRect)textRectForBounds:(CGRect)bounds {
return [self getRectForBounds:[super textRectForBounds:bounds] withInset:_inset];
}
- (CGRect)placeholderRectForBounds:(CGRect)bounds {
return [self getRectForBounds:bounds withInset:_inset];
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
return [self getRectForBounds:[super editingRectForBounds:bounds] withInset:_inset];
}
- (CGRect)clearButtonRectForBounds:(CGRect)bounds {
return CGRectOffset([super clearButtonRectForBounds:bounds], -_inset.size.width, _inset.origin.y/2 - _inset.size.height/2);
}
@end
*_someTextField*来自nib/storyboard视图,带有MRDInsetTextField自定义类的用法示例
[(MRDInsetTextField*)_someTextField setInset:CGRectMake(5, 0, 5, 0)]; // left, top, right, bottom inset
其他回答
我子类化UITextField来处理这个,它支持左,上,右和底部的插入,以及清除按钮的定位。
MRDInsetTextField.h
#import <UIKit/UIKit.h>
@interface MRDInsetTextField : UITextField
@property (nonatomic, assign) CGRect inset;
@end
MRDInsetTextField.m
#import "MRDInsetTextField.h"
@implementation MRDInsetTextField
- (id)init
{
self = [super init];
if (self) {
_inset = CGRectZero;
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
_inset = CGRectZero;
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_inset = CGRectZero;
}
return self;
}
- (void)setInset:(CGRect)inset {
_inset = inset;
[self setNeedsLayout];
}
- (CGRect)getRectForBounds:(CGRect)bounds withInset:(CGRect)inset {
CGRect newRect = CGRectMake(
bounds.origin.x + inset.origin.x,
bounds.origin.y + inset.origin.y,
bounds.origin.x + bounds.size.width - inset.origin.x - inset.size.width,
bounds.origin.y + bounds.size.height - inset.origin.y - inset.size.height
);
return newRect;
}
- (CGRect)textRectForBounds:(CGRect)bounds {
return [self getRectForBounds:[super textRectForBounds:bounds] withInset:_inset];
}
- (CGRect)placeholderRectForBounds:(CGRect)bounds {
return [self getRectForBounds:bounds withInset:_inset];
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
return [self getRectForBounds:[super editingRectForBounds:bounds] withInset:_inset];
}
- (CGRect)clearButtonRectForBounds:(CGRect)bounds {
return CGRectOffset([super clearButtonRectForBounds:bounds], -_inset.size.width, _inset.origin.y/2 - _inset.size.height/2);
}
@end
*_someTextField*来自nib/storyboard视图,带有MRDInsetTextField自定义类的用法示例
[(MRDInsetTextField*)_someTextField setInset:CGRectMake(5, 0, 5, 0)]; // left, top, right, bottom inset
如果你有一个明确的按钮,接受的答案将不适合你。我们还应该警惕苹果在未来通过调用super来改变事情。
因此,为了确保文本不会与清除按钮重叠,让我们先从super中获取“默认”值,然后根据需要进行调整。
这段代码将在文本框的顶部、左侧和底部添加一个10px的insets:
@interface InsetTextField : UITextField
@end
@implementation InsetTextField
// Placeholder position
- (CGRect)textRectForBounds:(CGRect)bounds {
CGRect rect = [super textRectForBounds:bounds];
UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, 10, 0);
return UIEdgeInsetsInsetRect(rect, insets);
}
// Text position
- (CGRect)editingRectForBounds:(CGRect)bounds {
CGRect rect = [super editingRectForBounds:bounds];
UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, 10, 0);
return UIEdgeInsetsInsetRect(rect, insets);
}
// Clear button position
- (CGRect)clearButtonRectForBounds:(CGRect)bounds {
CGRect rect = [super clearButtonRectForBounds:bounds];
return CGRectOffset(rect, -5, 0);
}
@end
注意:UIEdgeInsetsMake接受参数的顺序是:上,左,下,右。
在从UITextField派生的类中,至少重写以下两个方法:
- (CGRect)textRectForBounds:(CGRect)bounds;
- (CGRect)editingRectForBounds:(CGRect)bounds;
如果你没有额外的内容,它可能就像这样简单:
return CGRectInset(bounds , 10, 10);
UITextField提供了几个可以覆盖的定位方法。
我想我可以提供一个快速解决方案
import UIKit
class TextField: UITextField {
let inset: CGFloat = 10
// placeholder position
override func textRectForBounds(bounds: CGRect) -> CGRect {
return CGRectInset(bounds , inset , inset)
}
// text position
override func editingRectForBounds(bounds: CGRect) -> CGRect {
return CGRectInset(bounds , inset , inset)
}
override func placeholderRectForBounds(bounds: CGRect) -> CGRect {
return CGRectInset(bounds, inset, inset)
}
}
斯威夫特 3+
import UIKit
class TextField: UITextField {
let inset: CGFloat = 10
// placeholder position
override func textRect(forBounds: CGRect) -> CGRect {
return forBounds.insetBy(dx: self.inset , dy: self.inset)
}
// text position
override func editingRect(forBounds: CGRect) -> CGRect {
return forBounds.insetBy(dx: self.inset , dy: self.inset)
}
override func placeholderRect(forBounds: CGRect) -> CGRect {
return forBounds.insetBy(dx: self.inset, dy: self.inset)
}
}
下面是在Swift 3中编写的相同子类UITextField。它与之前的Swift版本有很大的不同,正如你将看到的:
import UIKit
class MyTextField: UITextField
{
let inset: CGFloat = 10
// placeholder position
override func textRect(forBounds bounds: CGRect) -> CGRect
{
return bounds.insetBy(dx: inset, dy: inset)
}
// text position
override func editingRect(forBounds bounds: CGRect) -> CGRect
{
return bounds.insetBy(dx: inset, dy: inset)
}
override func placeholderRect(forBounds bounds: CGRect) -> CGRect
{
return bounds.insetBy(dx: inset, dy: inset)
}
}
顺便说一句,如果你只想控制一侧的插入,你也可以像下面这样做。如果你把一个图像放在UITextField的顶部,但你想让它在用户看来是在文本框中,那么这个只调整左边插图的特殊例子就很方便了:
override func editingRect(forBounds bounds: CGRect) -> CGRect
{
return CGRect.init(x: bounds.origin.x + inset, y: bounds.origin.y, width: bounds.width - inset, height: bounds.height)
}