Stroke Animation when Editing UITextField

I’m trying to add animation to the border of UITextField when edited by the user. The idea is to show line animation in the login page once the first text field is being edited and then after the user switches to the next textfield, the line should make a movement to the below text field. I have made an attempt which is not working as what I’m expecting. The following is the code I’m using:

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var verticSpace: NSLayoutConstraint!
@IBOutlet weak var usernameTxtField: UITextField!
@IBOutlet weak var passwordTxtField: UITextField!

weak var shapeLayer: CAShapeLayer?

let path = UIBezierPath()

let shapeLayerNew = CAShapeLayer()

override func viewDidLoad() {

    usernameTxtField.delegate = self

    passwordTxtField.delegate = self


func textFieldDidBeginEditing(_ textField: UITextField) {
    let path = UIBezierPath()

    if textField == usernameTxtField {
        if textField.text == "" {



    if passwordTxtField.isFirstResponder {

        let path2 = UIBezierPath()

        path2.move(to: CGPoint(x: usernameTxtField.frame.width, y: usernameTxtField.frame.height - shapeLayerNew.lineWidth))
        path2.addLine(to: CGPoint(x: usernameTxtField.frame.width, y: (usernameTxtField.frame.height - shapeLayerNew.lineWidth) + passwordTxtField.frame.height + verticSpace.constant))
        path2.addLine(to: CGPoint(x: 0, y: (usernameTxtField.frame.height - shapeLayerNew.lineWidth) + passwordTxtField.frame.height + verticSpace.constant))

        let combinedPath = path.cgPath.mutableCopy()
        shapeLayerNew.path = path2.cgPath

        let startAnimation = CABasicAnimation(keyPath: "strokeStart")
        startAnimation.fromValue = 0
        startAnimation.toValue = 0.8

        let endAnimation = CABasicAnimation(keyPath: "strokeEnd")
        endAnimation.fromValue = 0.2
        endAnimation.toValue = 1.0

        let animation = CAAnimationGroup()
        animation.animations = [startAnimation, endAnimation]
        animation.duration = 2
        shapeLayerNew.add(animation, forKey: "MyAnimation")



func startMyLine() {


    // create whatever path you want

    shapeLayerNew.fillColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor
    shapeLayerNew.strokeColor = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1).cgColor
    shapeLayerNew.lineWidth = 4

    path.move(to: CGPoint(x: 0, y: usernameTxtField.frame.height - shapeLayerNew.lineWidth))
    path.addLine(to: CGPoint(x: usernameTxtField.frame.width, y: usernameTxtField.frame.height - shapeLayerNew.lineWidth))

    // create shape layer for that path

    shapeLayerNew.path = path.cgPath

    // animate it


    let animation = CABasicAnimation(keyPath: "strokeEnd")
    animation.fromValue = 0
    animation.duration = 2
    shapeLayerNew.add(animation, forKey: "MyAnimation")

    // save shape layer

    self.shapeLayer = shapeLayerNew


And this is the result I’m getting:

And this is what I need to see:

Hi @maryoomi,

This post was moved to a different board that fits your topic of discussion a bit better. This means you’ll get better engagement on your post, and it keeps our Community organized so users can more easily find information.

As you’ll notice, your Topic is now in the Project Development Help and Advice board. No action is needed on your part; you can continue the conversation as normal here.

Let me know if you have any other questions or if I can help with anything else.