2

I am using the following code in Swift 4.2 to have Textfield bottom border:

extension UITextField {    

    func useUnderline() {
        let border = CALayer()
        let borderWidth = CGFloat(1.0)
        border.borderColor = UIColor.lightGray.cgColor
        border.frame = CGRect(origin: CGPoint(x: 0,y :self.frame.size.height - borderWidth), size: CGSize(width: self.frame.size.width, height: self.frame.size.height))
        border.borderWidth = borderWidth
        self.layer.addSublayer(border)
        self.layer.masksToBounds = true
    }
}

but in different model of iPhones I get a different behaviors. for example: in Iphone XR: enter image description here

and with iPhone X or 8:

enter image description here

Any solution to this issue would be appreciated.

0

2 Answers 2

3

I'm sure this problem does not depend on an iPhone model, but from the place where you call useUnderline(). If you will call useUnderline() from viewDidAppear, then the line will draw correct. Because the size of UIControls not yet actual when calling viewDidLoad and viewWillAppear. But keep in your mind you will have a problem with your extension because sublayers will be added to UITextField on every viewDidAppear execution.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much for your great answer. that was a very good point! :)
1

This could be a prime example where you must use a UITextField subclass instead of an extension. The accepted answer will work, but as suggested there, your TextField will get many layers added to it as the user uses his application.

The below subclass could solve this issue:

class CustomTextField: UITextField{

    let border = CAShapeLayer()

    override func layoutSubviews() {
        super.layoutSubviews()
        useUnderline()
    }

    func useUnderline(){
        if layer.sublayers?.contains(border) ?? false{
            border.removeFromSuperlayer()
        }
        border.path = UIBezierPath.init(rect: CGRect.init(x: 0, y: self.bounds.height - 2, width: self.bounds.width, height: 2)).cgPath
        border.fillColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.3).cgColor
        self.layer.insertSublayer(border, at: 10)

    }
}

4 Comments

Thanks, SWAT. This is another professional answer. I like this as well. but, could you please how can I call useUnderline()?
useUnderLine is called every time your layoutSubViews is called. This would happen in initiation, orientation change, when the view is reused in a collectionView cell, etc. So it takes care of itself, you can say. If you want to call it by yourself, myTextFieldObject.useUnderline()
I get this error: Value of type 'UITextField?' has no member 'useUnderline' over using myTextFieldObject.useUnderline()
your object should be of type CustomTextField and not UITextField

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.