如何在 Swift 中仅显示 UITextField 的底部边框

How to only show bottom border of UITextField in Swift

我只想显示 底部边框并隐藏其他边。

我看到的输出:如您所见,我也看到了顶部、左侧和右侧的边框,它们是黑色的,我想将它们移除。只需要底部白色粗2.0边框。

我正在使用的代码 (source):

var border = CALayer()
var width = CGFloat(2.0)
border.borderColor = UIColor.whiteColor().CGColor
border.frame = CGRect(x: 0, y: tv_username.frame.size.height - width, width: tv_username.frame.size.width, height: tv_username.frame.size.height)

border.borderWidth = width
tv_username.backgroundColor = UIColor.clearColor()
tv_username.layer.addSublayer(border)
tv_username.layer.masksToBounds = true
tv_username.textColor = UIColor.whiteColor()

尝试用这种方式做,Swift 5.1:

var bottomLine = CALayer()
bottomLine.frame = CGRect(x: 0.0, y: myTextField.frame.height - 1, width: myTextField.frame.width, height: 1.0)
bottomLine.backgroundColor = UIColor.white.cgColor
myTextField.borderStyle = UITextField.BorderStyle.none
myTextField.layer.addSublayer(bottomLine)

您必须将 borderStyle 属性 设置为 None

如果您使用的是自动版式,请设置完美约束,否则底线将不会出现。

希望对您有所帮助。

Objective C

[txt.layer setBackgroundColor: [[UIColor whiteColor] CGColor]];
[txt.layer setBorderColor: [[UIColor grayColor] CGColor]];
[txt.layer setBorderWidth: 0.0];
[txt.layer setCornerRadius:12.0f];
[txt.layer setMasksToBounds:NO];
[txt.layer setShadowRadius:2.0f];
txt.layer.shadowColor = [[UIColor blackColor] CGColor];
txt.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
txt.layer.shadowOpacity = 1.0f;
txt.layer.shadowRadius = 1.0f;

Swift

textField.layer.backgroundColor = UIColor.whiteColor().CGColor
textField.layer.borderColor = UIColor.grayColor().CGColor
textField.layer.borderWidth = 0.0
textField.layer.cornerRadius = 5
textField.layer.masksToBounds = false
textField.layer.shadowRadius = 2.0
textField.layer.shadowColor = UIColor.blackColor().CGColor
textField.layer.shadowOffset = CGSizeMake(1.0, 1.0)
textField.layer.shadowOpacity = 1.0
textField.layer.shadowRadius = 1.0

我已经尝试了所有这些答案,但除了这个

没有人对我有用
  let borderWidth:CGFloat = 2.0 // what ever border width do you prefer 
    let bottomLine = CALayer()

    bottomLine.frame = CGRectMake(0.0, Et_textfield.height  - borderWidth, Et_textfield.width, Et_textfield.height )
    bottomLine.backgroundColor = UIColor.blueColor().CGColor
    bottomLine
    Et_textfield.layer.addSublayer(bottomLine)
    Et_textfield.layer.masksToBounds = true // the most important line of code

对于多个文本字段

  override func viewDidLoad() {


    configureTextField(x: 0, y: locationField.frame.size.height-1.0, width: locationField.frame.size.width, height:1.0, textField: locationField)
    configureTextField(x: 0, y: destinationField.frame.size.height-1.0, width: destinationField.frame.size.width, height:1.0, textField: destinationField)
    configureTextField(x: 0, y: originField.frame.size.height-1.0, width: originField.frame.size.width, height:1.0, textField: originField)
    configureTextField(x: 0, y: nameField.frame.size.height-1.0, width: nameField.frame.size.width, height:1.0, textField: nameField)

    locationField.text="Hello"
    super.viewDidLoad()

    // Do any additional setup after loading the view.
}

func configureTextField(x:CGFloat,y:CGFloat,width:CGFloat,height:CGFloat,textField:UITextField)

{
    let bottomLine = CALayer()
    bottomLine.frame = CGRect(x: x, y: y, width: width, height: height)
    bottomLine.backgroundColor = UIColor.white.cgColor
    textField.borderStyle = UITextBorderStyle.none
    textField.layer.addSublayer(bottomLine)


}

Swift 3:

只是 子类 你的 UITextField

class BottomBorderTF: UITextField {

var bottomBorder = UIView()
override func awakeFromNib() {

    //MARK: Setup Bottom-Border
    self.translatesAutoresizingMaskIntoConstraints = false
    bottomBorder = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    bottomBorder.backgroundColor = UIColor.orange
    bottomBorder.translatesAutoresizingMaskIntoConstraints = false
    addSubview(bottomBorder)
    //Mark: Setup Anchors
    bottomBorder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    bottomBorder.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    bottomBorder.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
    bottomBorder.heightAnchor.constraint(equalToConstant: 1).isActive = true // Set Border-Strength

   }
}

从@Ashish 的回答中想到,很久以前在 Objective-C 中使用了相同的方法,但实施扩展会更有用。

extension UITextField {
    func addBottomBorder(){
        let bottomLine = CALayer()
        bottomLine.frame = CGRect(x: 0, y: self.frame.size.height - 1, width: self.frame.size.width, height: 1)
        bottomLine.backgroundColor = UIColor.white.cgColor
        borderStyle = .none
        layer.addSublayer(bottomLine)
    }
}

在您的控制器中:

self.textField.addBottomBorder()

可以向您的方法添加更多参数,例如添加边框高度、颜色。

Textfield 底部边框已设置,但 devices.So 底部边框不适合 textfield.I 的更多问题检索该问题代码如下 它工作正常 swift4.2

let bottomLine = CALayer()
        bottomLine.frame = CGRect(x: 0.0, y: textField.frame.height - 1, width: screenSize.width - 32, height: 1.0)
        bottomLine.backgroundColor = UIColor(hex: 0xD5D5D5).cgColor
        textField.borderStyle = UITextField.BorderStyle.none
        textField.layer.addSublayer(bottomLine)

@mina-fawzy 我喜欢 Mina Fawzy 提供的包含 masksToBounds 的答案...

我 运行 解决了这个问题,我试图为 UITextField 的底部边框设置样式,使用 CGRect 的评论对我有用,但是,我运行在使用不同的屏幕尺寸时遇到问题,或者如果我将方向从纵向更改为横向视图。

即。我的 Xcode Main.storyboard 是用 iPhone XS Max 设计的,UITextField 被限制为距屏幕 left/right 20 点。在我的 viewDidLoad() 中,我使用 CGRect 方法对 UITextField(文本字段)进行了样式化,使矩形的宽度等于 textfield.frame.width

在 iPhone XS Max 上测试时,一切正常,但是,当我在 iPhone 7(较小的屏幕宽度)上测试时,CGRect 抓住了 iPhone viewDidLoad() 期间的 XS Max,导致矩形(底线)太宽,右边缘超出屏幕。同样,当我在 iPad 屏幕上进行测试时,底线太短了。而且,在任何设备上,旋转到横向视图都不会重新计算底线所需的矩形大小。

我找到的最佳解决方案 是将 CGRect 的宽度设置为大于最长的 iPad 维度(我 运行domly 选择了 2000)然后添加 textfield.layer.masksToBounds = true。这 完美 因为现在该行从一开始就很长,不需要重新计算,并且无论屏幕大小或方向。

谢谢 Mina,希望这对遇到同样问题的其他人有所帮助!

使用 CALayer 的解决方案不好,因为当设备旋转时下划线不会改变宽度。

class UnderlinedTextField: UITextField {

    override func awakeFromNib() {
        super.awakeFromNib()

        let bottomLine = CALayer()
        bottomLine.frame = CGRect(x: 0, y: self.frame.size.height, width: UIScreen.main.bounds.width, height: 1)
        bottomLine.bounds = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: self.frame.size.height)
        bottomLine.backgroundColor = UIColor.black.cgColor
        borderStyle = .none
        layer.addSublayer(bottomLine)
        layer.masksToBounds = true
    }
}

最好的解决方案是使用 UIView。

class UnderlinedTextField: UITextField {
    private let defaultUnderlineColor = UIColor.black
    private let bottomLine = UIView()

    override func awakeFromNib() {
        super.awakeFromNib()

        borderStyle = .none
        bottomLine.translatesAutoresizingMaskIntoConstraints = false
        bottomLine.backgroundColor = defaultUnderlineColor

        self.addSubview(bottomLine)
        bottomLine.topAnchor.constraint(equalTo: self.bottomAnchor, constant: 1).isActive = true
        bottomLine.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        bottomLine.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        bottomLine.heightAnchor.constraint(equalToConstant: 1).isActive = true
    }

    public func setUnderlineColor(color: UIColor = .red) {
        bottomLine.backgroundColor = color
    }

    public func setDefaultUnderlineColor() {
        bottomLine.backgroundColor = defaultUnderlineColor
    }
}

首先将borderStyle属性设置为.none.

还有,别忘了在viewDidAppear(_:)方法中调用这个方法的最佳时机。

为了方便使用,您可以使用扩展程序:

extension UIView {
    func addBottomBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x: 0, y: self.frame.size.height - width, 
                              width: self.frame.size.width, height: width)
        self.layer.addSublayer(border)
    }
}

这样称呼它:

textfield.addBottomBorderWithColor(color: UIColor.lightGray, width: 0.5)

对于那些正在寻找适用于 Autolayout、IBInspectable 和 Storyboard 的解决方案的人,将 class UITextField 子class 到您的自定义文本字段 class 并添加这些:

func setUnderline() {
    for sub in self.subviews {
        sub.removeFromSuperview()
    }
    if underlineStyle == true {
        var bottomBorder = UIView()
        bottomBorder = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
        bottomBorder.backgroundColor = borderColor  //YOUR UNDERLINE COLOR HERE
        bottomBorder.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(bottomBorder)

        bottomBorder.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        bottomBorder.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        bottomBorder.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        bottomBorder.heightAnchor.constraint(equalToConstant: underlineHeight).isActive = true
        layoutIfNeeded()
    }
}

@IBInspectable var underlineStyle: Bool = false {
    didSet {
       setUnderline()
    }
}

@IBInspectable var underlineHeight: CGFloat = 0 {
    didSet {
        setUnderline()
    }
}

对于 swift 4. 这对我有用。

   let myfield:UITextField = {
        let mf=UITextField()
        let atributePlaceHolder=NSAttributedString(string: "Text_description", attributes:[NSAttributedString.Key.foregroundColor :UIColor.darkGray])
        mf.textColor = .gray
        mf.attributedPlaceholder=atributePlaceHolder
        mf.layer.borderColor = UIColor.black.cgColor
        mf.layer.backgroundColor = UIColor.white.cgColor
        mf.layer.borderWidth = 0.0
        mf.layer.shadowOffset = CGSize(width: 0, height: 1.0)
        mf.layer.shadowOpacity = 1.0
        mf.layer.shadowRadius = 0.0
        return mf
    }()

使用扩展和 Swift 5.3

extension UITextField {
    internal func addBottomBorder(height: CGFloat = 1.0, color: UIColor = .black) {
        let borderView = UIView()
        borderView.backgroundColor = color
        borderView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(borderView)
        NSLayoutConstraint.activate(
            [
                borderView.leadingAnchor.constraint(equalTo: leadingAnchor),
                borderView.trailingAnchor.constraint(equalTo: trailingAnchor),
                borderView.bottomAnchor.constraint(equalTo: bottomAnchor),
                borderView.heightAnchor.constraint(equalToConstant: height)
            ]
        )
    }
}

Swift 5.

extension UITextField {
    let bottomLine = UIView()
    bottomLine.backgroundColor = .black
    borderStyle = .none
        
    self.addSubview(bottomLine)

    NSLayoutConstraint.activate([
        bottomLine.topAnchor.constraint(equalTo: bottomAnchor + 10),
        bottomLine.leadingAnchor.constraint(equalTo: leadingAnchor),
        bottomLine.trailingAnchor.constraint(equalTo: trailingAnchor),
        bottomLine.heightAnchor.constraint(equalToConstant: 1)
    ]) 
}