自定义 UITextField 中的边框宽度和占位符

Border width and placeholder in custom UITextField

我想制作这个 TextField

所以我写这个class

class UnderLineTextField:UITextField{

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let border = CALayer()
        let width = CGFloat(2.0)
        border.borderColor = UIColor.darkgray().cgColor
        border.frame = CGRect(x: 0, y: frame.size.height - width, width: frame.size.width, height: frame.size.height)

        textColor = UIColor.gold()
        backgroundColor = UIColor.clear

        border.borderWidth = width
        layer.addSublayer(border)
        layer.masksToBounds = true

        attributedPlaceholder = NSAttributedString(string: "",
                                                  attributes: [NSAttributedStringKey.foregroundColor: UIColor.darkgray()])}
}

但是有两个问题

  1. 下划线不等于TextField,如果我加宽width: frame.size.width + 500,问题可以解决,但为什么呢?我应该传递给 width: 的正确值是多少?

  2. attributedPlaceholder会替换掉我在xib中设置的placeholder,如何在不添加空字符串的情况下更改placeholder?

  1. The underline is not equal to TextField, if I add more width width: frame.size.width + 500, the problem can be fixed, but why? what is the correct value I should pass to width:?

您应该将抽奖下划线代码设为 draw(_ rect: CGRect) 而不是 init。因为你使用 autolayout,所以你在 init 中得到的宽度与你在 运行 app.

中看到的 width 不同
  1. attributedPlaceholder will replace the placeholder I set in xib, how can I change placeholder without adding empty string?

您也可以根据 draw(_ rect: CGRect) 中的占位符重绘 attributedPlaceholder

attributedPlaceholder = NSAttributedString(
    string: self.placeholder,
    attributes: [NSAttributedStringKey.foregroundColor: UIColor.darkgray()]
)

对于UITextField下划线使用这个...

let border = CALayer()
let width = CGFloat(1.0)
border.borderColor = UIColor.gray.cgColor
border.frame = CGRect(x: 0, y: textField.frame.size.height - width, width:  textField.frame.size.width, height: textField.frame.size.height)

border.borderWidth = width
textField.layer.addSublayer(border)
textField.layer.masksToBounds = true

看来你的代码没问题。

使用以下代码设置占位符:

class UnderLineTextField:UITextField{

    @IBInspectable var borderColor: UIColor = UIColor.white {
        didSet {
            layer.borderColor = borderColor.cgColor

        }
    }
    @IBInspectable var placeHolderText: String = "default place holder" {
        didSet {
            attributedPlaceholder = NSAttributedString(string: placeHolderText,
                                                       attributes: [NSAttributedStringKey.foregroundColor: UIColor.darkGray])}

        }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let border = CALayer()
        let width = CGFloat(2.0)
        border.borderColor = UIColor.darkGray.cgColor
        border.frame = CGRect(x: 0, y: frame.size.height - width, width: frame.size.width, height: frame.size.height)

        textColor = UIColor.lightGray
        backgroundColor = UIColor.clear

        border.borderWidth = width
        layer.addSublayer(border)
        layer.masksToBounds = true

        attributedPlaceholder = NSAttributedString(string: placeHolderText,
                                                   attributes: [NSAttributedStringKey.foregroundColor: UIColor.darkGray])}
}

并在情节提要中设置占位符:

结果如下所示:

嘿,已经有很多答案了:),让我们看看这个详细的答案是否可以帮助您实现更多目标: 如果可能的话,我更喜欢使用扩展而不是继承。

extension UITextField {

func setTextColor(_ color: UIColor, font: UIFont) {

    self.textColor = color
    self.font = font
}

func setBottomBorder(with color: UIColor, width: CGFloat) {
    self.borderStyle = .none
    self.layer.backgroundColor = UIColor.white.cgColor // bg color of your choice

    self.layer.masksToBounds = false
    self.layer.shadowColor = color.cgColor
    self.layer.shadowOffset = CGSize(width: 0.0, height: width)
    self.layer.shadowOpacity = 1.0
    self.layer.shadowRadius = 0.0
}


func setPlaceHolderAttributes(placeHolderText : String, colour : UIColor , font : UIFont){

    self.attributedPlaceholder = NSAttributedString(string:placeHolderText, attributes:[NSAttributedStringKey.foregroundColor: colour , NSAttributedStringKey.font : font])
}

}

//MARK: 给文本插入

class MyTextField: UITextField {

override func textRect(forBounds bounds: CGRect) -> CGRect {
    return CGRect.init(x:10, y:2, width:bounds.width-20, height:bounds.height - 4)
}

override func editingRect(forBounds bounds: CGRect) -> CGRect {
    return textRect(forBounds: bounds)
}

}

而且我更喜欢从代码配置 UI,它会加快您的编码速度并实现从一个地方进行项目明智的更改,因此您可以从代码中完成:

 let font: UIFont = UIFont.systemFont(ofSize: 14.0)
    let placeHolderTextColor: UIColor = UIColor.brown
    let textColor: UIColor = UIColor.darkText

    nameTextField.setBottomBorder(with: UIColor.darkGray, width: 1.0)
    passwordTextField.setBottomBorder(with: UIColor.darkGray, width: 1.0)

    nameTextField.setPlaceHolderAttributes(placeHolderText: "Name", colour: placeHolderTextColor, font: font)
    nameTextField.setTextColor(textColor, font: font)

    passwordTextField.setPlaceHolderAttributes(placeHolderText: "Password", colour: placeHolderTextColor, font: font)
    passwordTextField.setTextColor(textColor, font: font)

希望这对您有所帮助:)