UITextField的文本插入?

Run*_*oop 402 cocoa-touch uitextfield ios

我想插页的文字UITextField.

这可能吗?

azd*_*dev 615

覆盖-textRectForBounds:只会更改占位符文本的插入内容.要更改可编辑文本的插入,您还需要覆盖-editingRectForBounds:

// placeholder position
- (CGRect)textRectForBounds:(CGRect)bounds {
     return CGRectInset(bounds, 10, 10);
}

// text position
- (CGRect)editingRectForBounds:(CGRect)bounds {
     return CGRectInset(bounds, 10, 10);
}
Run Code Online (Sandbox Code Playgroud)

  • 我建议在调用CGRectInset(bounds,10,10)之前调用[super textRectForBounds:bounds]和[super editingRectForBounds:bounds].这将解决清除按钮覆盖问题. (20认同)
  • 这个解决方案对我有用,虽然我使用了CGRectInset的返回值(bounds,9,0); 我还需要为textRectForBounds,editingRectForBounds和placeholderRectForBounds设置此值. (10认同)
  • 这个解决方案与clearButton不兼容.TextField覆盖按钮内的文本. (2认同)
  • 用于放置ClearButton:`-(CGRect)clearButtonRectForBounds:(CGRect)bounds {return CGRectMake(x,y,w,h); }`在这里找到:http://stackoverflow.com/questions/5361369/ios-programming-frame-bounds-and-center (2认同)

chu*_*n20 293

我能够通过以下方式完成:

myTextField.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0);
Run Code Online (Sandbox Code Playgroud)

当然记得导入QuartzCore并将Framework添加到您的项目中.

  • +1为创造力,但这有点问题,它移动也删除文本字段内的按钮 (38认同)
  • 你可以做myTextField.layer.sublayers这是一个包含所有子层的数组...如果它的UIImageView < - 我假设X是一个图像..或者可能是UIButton ......或者你可以循环遍历每一个并查看哪一个属于哪个子视图...但myfield.layer.sublayerTransform所有子图层,因此X按钮移动... (2认同)
  • 这是没有子类化的最佳解决方案,不需要在屏幕上放置额外的,不必要的视图!+1! (2认同)

dra*_*ard 167

在从UITextField派生的类中,至少覆盖以下两个方法:

- (CGRect)textRectForBounds:(CGRect)bounds;
- (CGRect)editingRectForBounds:(CGRect)bounds;
Run Code Online (Sandbox Code Playgroud)

如果您没有其他内容,它可能就像这样简单:

return CGRectInset(bounds , 10, 10);
Run Code Online (Sandbox Code Playgroud)

UITextField提供了几种可以覆盖的定位方法.

  • 在我看来这是一个可怕的黑客 - 你还需要覆盖` - (CGRect)borderRectForBounds:(CGRect)边界; - (CGRect)placeholderRectForBounds:(CGRect)bounds; - (CGRect)clearButtonRectForBounds:(CGRect)bounds; - (CGRect)leftViewRectForBounds:(CGRect)bounds; - (CGRect)rightViewRectForBounds:(CGRect)bounds;` (5认同)
  • 是的,如果你不覆盖editingRectForBounds,你可以在文本字段的左上角进行编辑时获得文本. - (CGRect)editingRectForBounds:(CGRect)bounds {return CGRectInset(bounds,10,10); } (2认同)

rob*_*tti 164

如果您只需要左边距,可以试试这个:

UItextField *textField = [[UITextField alloc] initWithFrame:...];
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, textField.frame.size.height)];
leftView.backgroundColor = textField.backgroundColor;
textField.leftView = leftView;
textField.leftViewMode = UITextFieldViewModeAlways;
Run Code Online (Sandbox Code Playgroud)

这个对我有用.我希望这可能有所帮助.

  • 这比仅用于获取插图的子类更容易,并允许您在左侧添加任意视图(您也可以使用rightView在右侧放置一些内容).比接受的答案恕我直言更好. (17认同)
  • +1 easy,no-subclassing,设计用于处理textfield属性(而不是'hacking'). (3认同)

mas*_*ash 92

怎么样的@IBInspectable,@IBDesignable迅速类.

@IBDesignable
class TextField: UITextField {
    @IBInspectable var insetX: CGFloat = 6 {
       didSet {
         layoutIfNeeded()
       }
    }
    @IBInspectable var insetY: CGFloat = 6 {
       didSet {
         layoutIfNeeded()
       }
    }

    // placeholder position
    override func textRectForBounds(bounds: CGRect) -> CGRect {
        return CGRectInset(bounds , insetX , insetY)
    }

    // text position
    override func editingRectForBounds(bounds: CGRect) -> CGRect {
        return CGRectInset(bounds , insetX , insetY)
    }
}
Run Code Online (Sandbox Code Playgroud)

你会在故事板中看到这一点.

在此输入图像描述

更新 - 斯威夫特3

@IBDesignable
class TextField: UITextField {
    @IBInspectable var insetX: CGFloat = 0
    @IBInspectable var insetY: CGFloat = 0

    // placeholder position
    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: insetX, dy: insetY)
    }

    // text position
    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: insetX, dy: insetY)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我发现对 Y 的影响不受欢迎,我不想缩小文本的矩形,而是将其向下推向字段的基线。我将实现调整为`let rect = CGRect(x: bounds.minX, y: bounds.minY + insetY, width: bounds.width, height: bounds.height) return CGRectInset(rect , insetX , 0)` (2认同)

Chr*_*let 28

如果您有一个清除按钮,则接受的答案对您不起作用.我们也应该通过致电来防范苹果未来的变化super.

因此,为了确保文本不与清除按钮重叠,让我们从super第一个开始获取"默认"值,然后根据需要进行调整.

此代码将在文本字段的顶部,左侧和底部添加10px插入内容:

@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
Run Code Online (Sandbox Code Playgroud)

注意:UIEdgeInsetsMake按顺序获取参数:top,left,bottom,right.


smi*_*t04 18

以为我会提供一个Swift解决方案

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) 
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记`override func placeholderRectForBounds(bounds:CGRect) - > CGRect {return CGRectInset(bounds,inset,inset)}` (2认同)

Sam*_*fes 14

使用textRectForBounds:是正确的方法.我把它包装在我的子类中,所以你可以简单地使用它textEdgeInsets.请参见SSTextField.


lcl*_*lcl 13

截至2017年5月,Xcode 8.3.1的Swift 3版本:

 class TextField: UITextField {

    let inset: CGFloat = 8

    // 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)
    }
}
Run Code Online (Sandbox Code Playgroud)


kar*_*rim 12

对于那些正在寻找更简单解决方案的人.

UITextField里面添加一个UIView.为了模拟文本字段周围的插图,我保持10 px左边,宽度比视图小20 px.对于文本字段周围的圆角边框,请使用视图的边框

viewBG.layer.cornerRadius = 8.0;
viewBG.layer.borderColor = [UIColor darkGrayColor].CGColor;
viewBG.layer.borderWidth = 1.0;
Run Code Online (Sandbox Code Playgroud)

  • 老实说,只需将UIView放在UITextField后面就是最好最简单的解决方案.使UITextField透明并完成.我将它与UITextView对齐 - 结果是大约6个像素插入.比创建子类更容易也更灵活... (2认同)

Gol*_*den 12

您可以通过设置leftView为UITextField设置文本插入.

像这样:

UITextField *yourTextField = [[UITextField alloc] init];
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];
leftView.backgroundColor = [UIColor clearColor];
yourTextField.leftViewMode = UITextFieldViewModeAlways;
yourTextField.leftView = leftView;
Run Code Online (Sandbox Code Playgroud)


Bro*_*son 11

向UITextField添加填充的一种好方法是继承UITextField并添加edgeInsets属性.然后设置edgeInsets,并相应地绘制UITextField.这也可以使用自定义leftView或rightView集正常运行.

OSTextField.h

#import <UIKit/UIKit.h>

@interface OSTextField : UITextField

@property (nonatomic, assign) UIEdgeInsets edgeInsets;

@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


Lon*_*Guy 11

迅速

    // adjust place holder text
    let paddingView = UIView(frame: CGRectMake(0, 0, 10, usernameOrEmailField.frame.height))
    usernameOrEmailField.leftView = paddingView
    usernameOrEmailField.leftViewMode = UITextFieldViewMode.Always
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常便宜且简单的解决方法。谢谢! (2认同)

Bru*_*ino 7

斯威夫特 4.2版本:

import UIKit

class InsetTextField: UITextField {

  let inset: CGFloat = 10

  override func textRect(forBounds bounds: CGRect) -> CGRect {
    return bounds.insetBy(dx: inset, dy: inset)
  }


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

}
Run Code Online (Sandbox Code Playgroud)


小智 6

我在 IB 中做了这个,在那里我在 textView 后面创建了一个 UIView,它有点长。将 textField 背景颜色设置为清除。 在此处输入图片说明


zgo*_*ski 6

Swift 3 /可在界面构建器中设计/分离水平和垂直昆虫/开箱即用

@IBDesignable
class TextFieldWithPadding: UITextField {

@IBInspectable var horizontalInset: CGFloat = 0
@IBInspectable var verticalInset: CGFloat = 0

override func textRect(forBounds bounds: CGRect) -> CGRect {
    return bounds.insetBy(dx: horizontalInset, dy: verticalInset)
}

override func editingRect(forBounds bounds: CGRect) -> CGRect {
    return bounds.insetBy(dx: horizontalInset , dy: verticalInset)
}

override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
    return bounds.insetBy(dx: horizontalInset, dy: verticalInset)
}
}
Run Code Online (Sandbox Code Playgroud)

用法:

用法

&

在此输入图像描述


Chr*_*lay 5

UITextField正如@Adam Waite 指出的那样,您必须继承子类是荒谬的,因为已经实现了这些方法。这是一个公开工厂方法的 swift 扩展,也可以在我们的类别 repo 中找到

private class InsetTextField: UITextField {
    var insets: UIEdgeInsets

    init(insets: UIEdgeInsets) {
        self.insets = insets
        super.init(frame: CGRectZero)
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("not intended for use from a NIB")
    }

    // placeholder position
    override func textRectForBounds(bounds: CGRect) -> CGRect {
        return super.textRectForBounds(UIEdgeInsetsInsetRect(bounds, insets))
    }

    // text position
    override func editingRectForBounds(bounds: CGRect) -> CGRect {
        return super.editingRectForBounds(UIEdgeInsetsInsetRect(bounds, insets))
    }
}

extension UITextField {

    class func textFieldWithInsets(insets: UIEdgeInsets) -> UITextField {
        return InsetTextField(insets: insets)
    }

}
Run Code Online (Sandbox Code Playgroud)


Gen*_*rco 5

这是用 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)
        }
    }
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果您只想控制一侧的插入,您也可以执行如下操作。如果您将图像放置在 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)
        }
Run Code Online (Sandbox Code Playgroud)


Max*_*Max 5

这是我不做任何子类就发现的最快方法:

UIView *spacerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10., 10.)];
[textField setLeftViewMode:UITextFieldViewModeAlways];
[textField setLeftView:spacerView];
Run Code Online (Sandbox Code Playgroud)

在Swift中:

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


Mus*_*les 5

带有额外使用示例的Swift 5 版本的Christopher 答案

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

}
Run Code Online (Sandbox Code Playgroud)

用法: -

class ViewController: UIViewController {

  private let passwordTextField: UITextField = {

        let textField = UITextField.textFieldWithInsets(insets: UIEdgeInsets(top: 10, left: 15, bottom: 10, right: 15))
     // ---
   
        return textField
    }()

}
Run Code Online (Sandbox Code Playgroud)