在UITextField的开头创建空间

时间:2014-08-18 16:04:32

标签: ios swift cocoa-touch uitextfield

我想在UITextField的开头留一点空间,就像这里一样: Add lefthand margin to UITextField

但我不知道如何用Swift做到这一点。

23 个答案:

答案 0 :(得分:217)

这就是我现在正在使用的:

Swift 4.2

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

我从不设置其他填充但你可以调整。这个课程没有在文本字段上处理rightView和leftView。如果你想要正确处理它,你可以使用类似的东西(例如在objc中我只需要rightView:

- (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;
}

答案 1 :(得分:140)

如果使用扩展名,则可以避免对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

希望这有帮助!

答案 2 :(得分:66)

X,Y,Z是您想要的值

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

答案 3 :(得分:35)

可以通过将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。所以现在键入将在视图之后开始。

由于

希望这有助于......

答案 4 :(得分:17)

使用经过测试的我的扩展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)) 

答案 5 :(得分:14)

简单的swift 3解决方案 - 将代码添加到viewDidLoad:

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

不需要可笑的长代码

答案 6 :(得分:13)

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

像这样,我们也可以创建右侧。(textFieldName.rightViewMode = .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)

答案 7 :(得分:8)

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

答案 8 :(得分:7)

子类化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()

答案 9 :(得分:6)

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

// 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

答案 10 :(得分:5)

此处Haagenti's answer已更新为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)
    }

}

参考:Upgrading To Swift 4.2

编辑:帐户中的清除按钮。

答案 11 :(得分:5)

将此代码放入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

它对我有用:)

答案 12 :(得分:4)

简单方法:通过扩展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)

答案 13 :(得分:4)

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

答案 14 :(得分:4)

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

答案 15 :(得分:1)

我更喜欢使用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))
    }
}

答案 16 :(得分:1)

*在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
        }
    }

}

答案 17 :(得分:1)

这一行代码救了我:

对于Xamarin.iOS:

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

对于Swift:

textField.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0);

答案 18 :(得分: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)
    }
}

答案 19 :(得分:0)

要扩展leftView和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
    
}

}

答案 20 :(得分:0)

textfield.layer.sublayerTransform = CATransform3DMakeTranslation(10, 0, 0)

答案 21 :(得分:0)

在大多数情况下,您可以将其视为技术问题,但所有示例都没有正确区分 framebounds 之间的区别。在子视图中引用视图的高度时,请使用 bounds - 否则一旦将某些变换应用于父视图,您可能会遇到麻烦。
请参阅下面的更新代码(基于 Pheepster 的回答)。

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

答案 22 :(得分:-3)

在 UITextField 的开头创建空间。
Swift 5+Xcode 12 中。

textFieldName.setLeftPaddingPoints(CGFloat(10))  
textFieldName.setRightPaddingPoints(CGFloat(10)