简体   繁体   English

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

[英]How to only show bottom border of UITextField in Swift

I want to show only bottom border and hide the other sides.我想显示下边框和隐藏的另一侧。

Output I see: As you can see I see the top, left and right borders also and they are black in color, I want to remove them.我看到的输出:正如你所看到的,我也看到了顶部、左侧和右侧的边框,它们是黑色的,我想删除它们。 Only need the bottom white thick 2.0 border.只需要底部白色厚2.0边框。

在此处输入图片说明

Code I am using ( 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()

Try to do by this way, with Swift 5.1:尝试通过这种方式使用 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)

You have to set the borderStyle property to None您必须将borderStyle属性设置为None

If you are using the autolayout then set perfect constraint else bottomline will not appear.如果您使用自动布局,则设置完美约束,否则底线将不会出现。

Hope it helps.希望能帮助到你。

Thought from @Ashish's answer, used same approach long ago in Objective-C but implementing extension will be more useful.从@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)
    }
}

In your controller:在您的控制器中:

self.textField.addBottomBorder()

Can add further parameters to your method, like adding border height, color.可以向您的方法添加更多参数,例如添加边框高度、颜色。

@mina-fawzy I liked the answer that included masksToBounds by Mina Fawzy... @mina-fawzy 我喜欢包括 Mina Fawzy 的masksToBounds的答案...

I ran into this issue where I was trying to style a bottom border of a UITextField , and the comments using a CGRect worked for me, however , I ran into issues when using different screen sizes, or if I changed the orientation to landscape view from the portrait.我在尝试为UITextField的底部边框设置样式时遇到了这个问题,并且使用CGRect的注释对我CGRect但是,在使用不同的屏幕尺寸时遇到了问题,或者如果我将方向更改为横向视图肖像。

ie. IE。 My Xcode Main.storyboard was designed with iPhone XS Max, with a UITextField constrained to be 20 points from the left/right of the screen.我的 Xcode Main.storyboard 是用 iPhone XS Max 设计的,UITextField 被限制在距离屏幕左/右 20 点的位置。 In my viewDidLoad() I stylized the UITextField (textfield) using the CGRect approach, making the width of the rectangle equal to textfield.frame.width .在我的viewDidLoad()我使用 CGRect 方法对UITextField (文本字段)进行了风格化,使矩形的宽度等于textfield.frame.width

When testing on the iPhone XS Max, everything worked perfectly, BUT, when I tested on iPhone 7 (smaller screen width) the CGRect was grabbing the width of the iPhone XS Max during the viewDidLoad() , causing the rectangle (bottom line) to be too wide, and the right edge went off the screen.在 iPhone XS Max 上测试时,一切正常,但是,当我在 iPhone 7(较小的屏幕宽度)上测试时,CGRect 在viewDidLoad()期间抓取了 iPhone XS Max 的宽度,导致矩形(底线)太宽了,右边缘离开了屏幕。 Similarly, when I tested on iPad screens, the bottom line was way too short.同样,当我在 iPad 屏幕上进行测试时,底线太短了。 And also, on any device, rotating to landscape view did not re-calculate the size of the rectangle needed for the bottom line.而且,在任何设备上,旋转到横向视图都不会重新计算底线所需的矩形大小。

The best solution I found was to set the width of the CGRect to larger than the longest iPad dimension (I randomly chose 2000) and THEN added textfield.layer.masksToBounds = true .我发现的最佳解决方案是将 CGRect 的宽度设置为大于最长的 iPad 尺寸(我随机选择 2000),然后添加textfield.layer.masksToBounds = true This worked perfectly because now the line is plenty long from the beginning, does not need to be re-calculated ever, and is clipped to the correct width of the UITextField no matter what screen size or orientation.很有效,因为现在这条线从一开始就很长,不需要重新计算,并且无论屏幕大小或方向如何,都被剪裁到 UITextField 的正确宽度。

Thanks Mina, and hope this helps others with the same issue!谢谢米娜,希望这能帮助其他有同样问题的人!

Objective C目标 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

I have tried all this answer but no one worked for me except this one我已经尝试了所有这些答案,但除了这个答案,没有人为我工作

  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

Swift 3:斯威夫特 3:

Just subclass your UITextField只需继承您的 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

   }
}

Solution which using CALayer is not good because when device is rotated the underline doesn't change width.使用 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
    }
}

The best solution is to use UIView.最好的解决方案是使用 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
    }
}

First set borderStyle property to .none.首先将borderStyle属性设置为 .none。

Also, don't forget that the best time to call this method in the viewDidAppear(_:) method.另外,不要忘记在viewDidAppear(_:)方法中调用此方法的最佳时间。

To make it handy, you can use an extension:为了方便使用,您可以使用扩展名:

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

Call it like:像这样称呼它:

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

For those looking for a solution that works for Autolayout, IBInspectable, and the Storyboard, subclass UITextField into your custom textfield class and add these:对于那些正在寻找适用于 Autolayout、IBInspectable 和 Storyboard 的解决方案的人,请将 UITextField 子类化到您的自定义文本字段类中并添加以下内容:

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 5.斯威夫特 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)
    ]) 
}

For multiple Text Field对于多个文本字段

  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)


}

Textfield bottom border set but some more issues for devices.So bottom border not fit in textfield.I retrieve that problem the code like this It works fine swift 4.2设置了文本字段底部边框,但设备还有一些问题。所以底部边框不适合文本字段。我检索该问题,代码如下 它可以正常工作 swift 4.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)

For swift 4. this works for me.对于 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
    }()

Using extension and Swift 5.3使用扩展和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)
            ]
        )
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM