如何在 UITextField 上设置下划线?

How can I set an underline on a UITextField?

我正在尝试在我的 UITextFields 上设置下划线。我尝试了几种方法,但其中 none 似乎有效。浏览了几个网站后,最推荐的方法如下:

extension UITextField {
    func setUnderLine() {
        let border = CALayer()
        let width = CGFloat(0.5)
        border.borderColor = UIColor.lightGray.cgColor
        border.frame = CGRect(x: 0, y: self.frame.size.height - width, width:  self.frame.size.width-10, height: self.frame.size.height)
        
        border.borderWidth = width
        self.layer.addSublayer(border)
        self.layer.masksToBounds = true
    }
}

我想不出上面的代码为什么不起作用的任何原因,但我看到的所有答案都是几年前发布的。

有人可以告诉我我做错了什么吗?

我在您发布的代码中看到的一个问题是,如果调整文本字段的大小,它不会更新图层。每次调用 setUnderLine() 函数时,它都会添加一个新层,然后就不管它了。

我建议子类化 UITextField。该代码可能如下所示:

class UnderlinedTextField: UITextField {

    let underlineLayer = CALayer()

    /// Size the underline layer and position it as a one point line under the text field.
    func setupUnderlineLayer() {
        var frame = self.bounds
        frame.origin.y = frame.size.height - 1
        frame.size.height = 1

        underlineLayer.frame = frame
        underlineLayer.backgroundColor = UIColor.blue.cgColor
    }

    // In `init?(coder:)` Add our underlineLayer as a sublayer of the view's main layer
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.layer.addSublayer(underlineLayer)
    }

    // in `init(frame:)` Add our underlineLayer as a sublayer of the view's main layer
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.layer.addSublayer(underlineLayer)
    }

    // Any time we are asked to update our subviews,
    // adjust the size and placement of the underline layer too
    override func layoutSubviews() {
        super.layoutSubviews()
        setupUnderlineLayer()
    }
}

这将创建一个如下所示的文本字段:

(请注意,如果您将模拟器旋转到横向模式,UnderlineTextField 会重新定位新文本字段边界的下划线层。)

请注意,将 UIView 添加到故事板可能更容易,固定在文本字段的底部,一像素高,使用您想要的下划线颜色。 (您将使用 AutoLayout 约束设置下划线视图,并为其指定背景色。)如果您这样做了,则根本不需要任何代码。

编辑:

我创建了一个 Github project 来演示这两种方法。 (link) 我还在示例应用程序中添加了基于视图的下划线。看起来像这样: