在 UITextField 的开头创建空间

我想在 UITextField 的开头留一点空间,就像这里一样: 向 UITextField 添加左边距

但我不知道怎么对付斯威夫特。

179039 次浏览

子类化 UITextField 是可行的。打开一个操场,添加以下代码:

class MyTextField : UITextField {
var leftTextMargin : CGFloat = 0.0


override func textRectForBounds(bounds: CGRect) -> CGRect {
var newBounds = bounds
newBounds.origin.x += leftTextMargin
return newBounds
}


override func editingRectForBounds(bounds: CGRect) -> CGRect {
var newBounds = bounds
newBounds.origin.x += leftTextMargin
return newBounds
}
}


let tf = MyTextField(frame: CGRect(x: 0, y: 0, width: 100, height: 44))
tf.text = "HELLO"
tf.leftTextMargin = 25
tf.setNeedsLayout()
tf.layoutIfNeeded()

这就是我现在使用的:

斯威夫特4.25

class TextField: UITextField {


let padding = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)


override open func textRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: padding)
}


override open func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: padding)
}


override open func editingRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: padding)
}
}

Swift 4

class TextField: UITextField {


let padding = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)


override open func textRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}


override open func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}


override open func editingRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}
}

斯威夫特3:

class TextField: UITextField {
    

let padding = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    

override func textRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}
    

override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}
    

override func editingRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}
}

我从来没有设置其他填充物,但你可以调整。这个类不处理 textfield 上的 right View 和 left View。如果你想正确地处理这个问题,你可以使用类似下面的例子:

- (CGRect)textRectForBounds:(CGRect)bounds {
CGRect paddedRect = UIEdgeInsetsInsetRect(bounds, self.insets);


if (self.rightViewMode == UITextFieldViewModeAlways || self.rightViewMode == UITextFieldViewModeUnlessEditing) {
return [self adjustRectWithWidthRightView:paddedRect];
}
return paddedRect;
}


- (CGRect)placeholderRectForBounds:(CGRect)bounds {
CGRect paddedRect = UIEdgeInsetsInsetRect(bounds, self.insets);


if (self.rightViewMode == UITextFieldViewModeAlways || self.rightViewMode == UITextFieldViewModeUnlessEditing) {
return [self adjustRectWithWidthRightView:paddedRect];
}
return paddedRect;
}


- (CGRect)editingRectForBounds:(CGRect)bounds {
CGRect paddedRect = UIEdgeInsetsInsetRect(bounds, self.insets);


if (self.rightViewMode == UITextFieldViewModeAlways || self.rightViewMode == UITextFieldViewModeWhileEditing) {
return [self adjustRectWithWidthRightView:paddedRect];
}
return paddedRect;
}


- (CGRect)adjustRectWithWidthRightView:(CGRect)bounds {
CGRect paddedRect = bounds;
paddedRect.size.width -= CGRectGetWidth(self.rightView.frame);


return paddedRect;
}

通过将 leftView/rightView设置为 UITextField,可以获得这样的余量。

更新为 Swift 4

// Create a padding view for padding on left
textField.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 15, height: textField.frame.height))
textField.leftViewMode = .always


// Create a padding view for padding on right
textField.rightView = UIView(frame: CGRect(x: 0, y: 0, width: 15, height: textField.frame.height))
textField.rightViewMode = .always

我刚刚在文本字段的左边和右边添加/放置了一个 UIView。所以现在输入将在视图之后开始。

谢谢

希望这个能帮上忙。

X,Y,Z 是你想要的值

textField.layer.sublayerTransform = CATransform3DMakeTranslation(x, y, z)

创建具有所需填充空间的 UIView,并将其添加到 textfield.leftView 成员,并将 textfield.leftViewMode 成员设置为 UITextFieldViewMode

// For example if you have textfield named title
@IBOutlet weak var title: UITextField!
// Create UIView
let paddingView : UIView = UIView(frame: CGRectMake(0, 0, 5, 20))
//Change your required space instaed of 5.
title.leftView = paddingView
title.leftViewMode = UITextFieldViewMode.Always

这是一个很好的延期案例。通过使用扩展,不需要子类 UITextField,新的功能将可用于应用程序中的任何 UITextField:

extension UITextField {
func setLeftPaddingPoints(_ amount:CGFloat){
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height))
self.leftView = paddingView
self.leftViewMode = .always
}
func setRightPaddingPoints(_ amount:CGFloat) {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height))
self.rightView = paddingView
self.rightViewMode = .always
}
}

当我需要在应用程序的任何地方设置文本字段的填充时,我只需执行以下操作:

    textField.setLeftPaddingPoints(10)
textField.setRightPaddingPoints(10)

通过使用 Swift 扩展,该功能可以直接添加到 UITextField 中,而不需要子类化。

希望这个能帮上忙!

ScareCrow 在 Swift 3中的回答

let padding = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5);


override func textRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}


override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}


override func editingRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}

简单快捷的3解决方案-向 viewDidLoad 添加代码:

let indentView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 20))
textField.leftView = indentView
textField.leftViewMode = .always

没必要写这么长的代码

< p > 在 Swift 3中。 可以使用自定义 UITextField 和在其构造函数中设置的缩进。不需要在控制器中额外声明。译注:
class CustomTextField : UITextField {


private let indentView = UIView(frame: CGRect(x: 0, y:0, width: 10, height: 10))


required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.leftView = indentView
self.leftViewMode = .always
}
}

在 Swift 5中为 UITextField 创建填充视图

func txtPaddingVw(txt:UITextField) {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: 5, height: 5))
txt.leftViewMode = .always
txt.leftView = paddingView
}

把这个代码放进你的 viewDidLoad():

textField.delegate = self


let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: self.textField.frame.height))
textField.leftView = paddingView
textField.leftViewMode = UITextFieldViewMode.always

这对我很有效:)

Swift 4 Xcode 9

我喜欢 Peepster 的回答,但是我们不需要 VC 代码或任何子类就可以从扩展开始:

import UIKit


@IBDesignable
extension UITextField {


@IBInspectable var paddingLeftCustom: CGFloat {
get {
return leftView!.frame.size.width
}
set {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
leftView = paddingView
leftViewMode = .always
}
}


@IBInspectable var paddingRightCustom: CGFloat {
get {
return rightView!.frame.size.width
}
set {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
rightView = paddingView
rightViewMode = .always
}
}
}

简单的方法:通过扩展 UITextField 来实现这一点

extension UITextField {


func setPadding(left: CGFloat? = nil, right: CGFloat? = nil){
if let left = left {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: left, height: self.frame.size.height))
self.leftView = paddingView
self.leftViewMode = .always
}


if let right = right {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: right, height: self.frame.size.height))
self.rightView = paddingView
self.rightViewMode = .always
}
}


}

然后你可以这样设置任意边缘的填充:

textField.setPadding(left: 5, right: 5)

Swift 4.2和 Xcode 10

最初我的文本字段是这样的。

enter image description here

在左侧添加填充后,我的文本字段是..。

enter image description here

//Code for left padding
textFieldName.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: textFieldName.frame.height))
textFieldName.leftViewMode = .always

像这样,我们也可以创建右侧

如果你想要 SharedInstance 类型代码(写一次使用每个软件)看到下面的代码。

//This is my shared class
import UIKit
class SharedClass: NSObject {
static let sharedInstance = SharedClass()


//This is my padding function.
func textFieldLeftPadding(textFieldName: UITextField) {
// Create a padding view
textFieldName.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 3, height: textFieldName.frame.height))
textFieldName.leftViewMode = .always//For left side padding
textFieldName.rightViewMode = .always//For right side padding
}


private override init() {


}
}

现在像这样调用这个函数。

//This single line is enough
SharedClass.sharedInstance.textFieldLeftPadding(textFieldName:yourTF)

下面是 哈根蒂的答案更新到 Swift 4.2:

class PaddedTextField: UITextField {


func getPadding(plusExtraFor clearButtonMode: ViewMode) -> UIEdgeInsets {
var padding = UIEdgeInsets(top: 11, left: 16, bottom: 11, right: 16)


// Add additional padding on the right side when showing the clear button
if self.clearButtonMode == .always || self.clearButtonMode == clearButtonMode {
padding.right = 28
}


return padding
}


override open func textRect(forBounds bounds: CGRect) -> CGRect {
let padding = getPadding(plusExtraFor: .unlessEditing)
return bounds.inset(by: padding)
}


override open func placeholderRect(forBounds bounds: CGRect) -> CGRect {
let padding = getPadding(plusExtraFor: .unlessEditing)
return bounds.inset(by: padding)
}


override open func editingRect(forBounds bounds: CGRect) -> CGRect {
let padding = getPadding(plusExtraFor: .whileEditing)
return bounds.inset(by: padding)
}


}

参考资料: 升级到 Swift 4.2

解释清除按钮。

我更喜欢使用 IBDesignable类和 IBInspectable属性来允许我通过 Xcode 故事板设置填充并保持它的可重用性。我还更新了代码,以便在 Swift 4中工作。

import Foundation
import UIKit


@IBDesignable
class PaddableTextField: UITextField {


var padding = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)


@IBInspectable var left: CGFloat = 0 {
didSet {
adjustPadding()
}
}


@IBInspectable var right: CGFloat = 0 {
didSet {
adjustPadding()
}
}


@IBInspectable var top: CGFloat = 0 {
didSet {
adjustPadding()
}
}


@IBInspectable var bottom: CGFloat = 0 {
didSet {
adjustPadding()
}
}


func adjustPadding() {
padding = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)


}


override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
}


override func textRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: UIEdgeInsets(top: top, left: left, bottom: bottom, right: right))
}


override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: UIEdgeInsets(top: top, left: left, bottom: bottom, right: right))
}


override func editingRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: UIEdgeInsets(top: top, left: left, bottom: bottom, right: right))
}
}

* 在 Swift 5中扩展 UITextField *

import UIKit


@IBDesignable
extension UITextField {


@IBInspectable var paddingLeftCustom: CGFloat {
get {
return leftView!.frame.size.width
}
set {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
leftView = paddingView
leftViewMode = .always
}
}


@IBInspectable var paddingRightCustom: CGFloat {
get {
return rightView!.frame.size.width
}
set {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
rightView = paddingView
rightViewMode = .always
}
}


}

这一行代码救了我:

对于 Xamarin.iOS:

textField.Layer.SublayerTransform = CATransform3D.MakeTranslation(5, 0, 0);

斯威夫特:

textField.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0);
//MARK:-  Use this class for different type of Roles


import UIKit


class HelperExtensionViewController: UIViewController {


}


//MARK:- Extension


extension UIImageView
{
func setImageCornerRadius()
{
self.layer.cornerRadius = self.frame.size.height/2
self.clipsToBounds = true
}


func setImageCornerRadiusInPoints(getValue:CGFloat)
{
self.layer.cornerRadius = getValue
self.clipsToBounds = true
}
}


extension UIButton
{
func setButtonCornerRadiusOnly()
{
self.layer.cornerRadius = self.frame.size.height/2
self.clipsToBounds = true
}


func setBtnCornerRadiusInPoints(getValue:CGFloat)
{
self.layer.cornerRadius = getValue
self.clipsToBounds = true
}




}


extension UITextField
{
func setTextFieldCornerRadiusWithBorder()
{
self.layer.cornerRadius = self.frame.size.height/2
self.layer.borderColor = UIColor.darkGray.cgColor
self.backgroundColor = UIColor.clear
self.layer.borderWidth = 0.5
self.clipsToBounds = true
}


func setLeftPaddingPoints(_ amount:CGFloat){
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height))
self.leftView = paddingView
self.leftViewMode = .always
}
func setRightPaddingPoints(_ amount:CGFloat) {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height))
self.rightView = paddingView
self.rightViewMode = .always
}
}






extension UIView
{


func setCornerRadius()
{
self.layer.cornerRadius = self.frame.size.height/2
self.clipsToBounds = true
}


// OUTPUT 1
func setViewCornerRadiusWithBorder()
{
self.layer.cornerRadius = self.frame.size.height/2
self.layer.borderColor = UIColor.init(red: 95.0/255.0, green: 229.0/255.0, blue: 206.0/255.0, alpha: 1.0).cgColor
self.backgroundColor = UIColor.clear
self.layer.borderWidth = 1.0
self.clipsToBounds = true
}


func layoutSubviews(myView:UIView)
{
let shadowPath = UIBezierPath(rect: myView.bounds)
myView.layer.masksToBounds = false
myView.layer.shadowColor = UIColor.lightGray.cgColor
myView.layer.shadowOffset = CGSize(width: -1.0, height: 2.0)
myView.layer.shadowOpacity = 0.5
myView.layer.shadowPath = shadowPath.cgPath
}


func layoutSubviews2(myView:UIView)
{
let shadowPath = UIBezierPath(rect: myView.bounds)
myView.clipsToBounds = true
myView.layer.masksToBounds = false
myView.layer.shadowColor = UIColor.black.cgColor
myView.layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
myView.layer.shadowOpacity = 0.2
myView.layer.shadowPath = shadowPath.cgPath


}


func setViewCornerRadiusInPoints(getValue:CGFloat)
{
self.layer.cornerRadius = getValue
self.clipsToBounds = true
}




func dropShadow(scale: Bool = true) {
layer.masksToBounds = false
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.5
layer.shadowOffset = CGSize(width: -1, height: 1)
layer.shadowRadius = 1


layer.shadowPath = UIBezierPath(rect: bounds).cgPath
layer.shouldRasterize = true
layer.rasterizationScale = scale ? UIScreen.main.scale : 1
}


// OUTPUT 2
func dropShadow(color: UIColor, opacity: Float = 0.5, offSet: CGSize, radius: CGFloat = 1, scale: Bool = true) {
layer.masksToBounds = false
layer.shadowColor = color.cgColor
layer.shadowOpacity = opacity
layer.shadowOffset = offSet
layer.shadowRadius = radius


layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath
layer.shouldRasterize = true
layer.rasterizationScale = scale ? UIScreen.main.scale : 1
}


func setGradientBackground(myview:UIView) {
let colorTop =  UIColor(red: 100.0/255.0, green: 227.0/255.0, blue: 237.0/255.0, alpha: 1.0).cgColor
let colorBottom = UIColor(red: 141.0/255.0, green: 109.0/255.0, blue: 164.0/255.0, alpha: 1.0).cgColor


let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorTop, colorBottom]
gradientLayer.locations = [1.0, 1.0]
gradientLayer.frame = myview.bounds


myview.layer.insertSublayer(gradientLayer, at:0)
}
}

使用我的扩展 Swift 5测试版:

extension UITextField {


enum PaddingSpace {
case left(CGFloat)
case right(CGFloat)
case equalSpacing(CGFloat)
}


func addPadding(padding: PaddingSpace) {


self.leftViewMode = .always
self.layer.masksToBounds = true


switch padding {


case .left(let spacing):
let leftPaddingView = UIView(frame: CGRect(x: 0, y: 0, width: spacing, height: self.frame.height))
self.leftView = leftPaddingView
self.leftViewMode = .always


case .right(let spacing):
let rightPaddingView = UIView(frame: CGRect(x: 0, y: 0, width: spacing, height: self.frame.height))
self.rightView = rightPaddingView
self.rightViewMode = .always


case .equalSpacing(let spacing):
let equalPaddingView = UIView(frame: CGRect(x: 0, y: 0, width: spacing, height: self.frame.height))
// left
self.leftView = equalPaddingView
self.leftViewMode = .always
// right
self.rightView = equalPaddingView
self.rightViewMode = .always
}
}
}

怎么用

// equal padding
yourTextField.addPadding(padding: .equalSpacing(10))


// padding right
yourTextField.addPadding(padding: .right(10))


// padding left
yourTextField.addPadding(padding: .left(10))

扩展 left-View 和 Swift5 + 的原始答案

class TextField: UITextField {


let padding = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
override open func textRect(forBounds bounds: CGRect) -> CGRect {
let paddedRect = bounds.inset(by: self.padding)
if (self.leftViewMode == .always || self.leftViewMode == .unlessEditing) {
return self.adjustRectOriginForLeftView(bounds: paddedRect)
}
return paddedRect
}
override open func placeholderRect(forBounds bounds: CGRect) -> CGRect {
let paddedRect = bounds.inset(by: self.padding)
if (self.leftViewMode == .always || self.leftViewMode == .unlessEditing) {
return self.adjustRectOriginForLeftView(bounds: paddedRect)
}
return paddedRect;
}
override open func editingRect(forBounds bounds: CGRect) -> CGRect {
let paddedRect = bounds.inset(by: self.padding);
if (self.leftViewMode == .always || self.leftViewMode == .unlessEditing) {
return self.adjustRectOriginForLeftView(bounds: paddedRect)
}
return paddedRect;
}


func adjustRectOriginForLeftView(bounds : CGRect) -> CGRect{
var paddedRect = bounds;
paddedRect.origin.x += self.leftView!.frame.width
return paddedRect
    

}

}

< p > 在 UITextField 的开头创建空间。 < br/> 在 Swift 5 + Xcode 12
textFieldName.setLeftPaddingPoints(CGFloat(10))
textFieldName.setRightPaddingPoints(CGFloat(10)
在大多数情况下,你可以把它看作是一个技术问题,但是所有的例子都没有正确地得到 framebounds之间的差异。当在子视图中引用视图的高度时,使用 bounds-否则,一旦对父视图应用了某种转换,您可能会遇到麻烦。< br/> 参见下面更新的代码(基于 Peepster 的回答)
extension UITextField {


func setLeftPadding(_ amount: CGFloat = 10) {


let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.bounds.size.height))
self.leftView = paddingView
self.leftViewMode = .always
}


func setRightPadding(_ amount: CGFloat = 10) {


let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.bounds.size.height))
self.rightView = paddingView
self.rightViewMode = .always
}
}