Creating a custom animated UITextfield in swift using CAShapeLayer and CABasicAnimation

Jawad Ali
4 min readOct 15, 2021

--

Source: Oleg Frolov

Few days back i was exploring dribble where i came across this beautiful Textfield animation design of Oleg Frolov. So i open up my Xcode and try to implement it using Core Animation. I used 3 CAShapeLayers giving them path using UIBezierPath and animate them using CABasicAnimation. In this tutorial, I will explain my implementation how to create customise UITextField with Core Animation. Let’s get to work!!!

Create a swift file to hold our customisation code. For the sake of this tutorial, we’ll call it “JDAnimatedTextField”. I added @IBDesignable to make it accessible in storyboards or xib and make it open for subclass. This file will hold the code responsible for creating and animating textField. Create a class using the same name extending UITextField like in the code below:

Next we need to create three CAShapeLayer. I usually create Factories for reusable UI elements lets create factory class first

Now we will create CAShapeLayer in JDAnimatedTextField

we will have one UILabel that will replace placeholder. we will animate its alpha when textfield become first responder and resign responder and lets write the initialiser of our custom textField and setup the view by adding layers and label as sublayer and subview respectively and add constraints. Add targets for editing begins ends or change to detect the events. we also don’t need border of this field so we set its style to none

To assign floating label text we take text from placeholder and to hide placeholder we assign it nil. we do that in init method and by overriding placeholder property as if its change programatically our floating label has updated placeholder text. This way we can control everything of our floating label placeholder. We can animate that as well as change colour, font, textAlignment and shadow.

Also we want our label to have same textAlignment as our textField so we override textAlignment

we need to hide cursor until our animation completes. So we override

func caretRect(for position: UITextPosition) -> CGRect

to return zero size until our animation completes their flow and when its completed we have matching size of cursor. so we resize cursor here as well

Now drawing part comes. we need to give our shapes a CGPath we will do that using UIBezierPath. But before that we need to understand from where we need to start the cursor movement. For that we will have a variable name cursorPosition. we will take cursor position on all touch events and on text change from UITextInput method. It gives us cursor current position

So lets define our two events that we attach in our common init method. we will discuss offset later.

lets draw the layers now using this cursor position

Dive into this drawing code we can see that we have cursor x position. On the basis of cursor x position we split our textField in two parts. one is right to that position and one left. so we draw one shape with circular end to the right of the cursor position and one to left and at cursor position we draw a vertical line that have stroke end 0 that means its hidden currently. we will show that once textField become responder and right and left layers complete their stroke animation. then we start this layer position and stroke animation. offset is actually circle radius. we don’t want to start writing from that area so we override textRect and editing rect with offset as well

For animations i write extension of CAShapeLayer to handle animations that i used in this project. I used simple stroke and origin Y position movement animation with completion block

lets jump to our animations on editing begins and end events that we attached in common init method

Now lets connect the dots and see the whole class and run it to see what we get after all these efforts

Create an instance of JDAnimatedTextField in your view controller like this

lets see the results

This textfield height is build on intrinsicContentSize so we need to increase its height by overriding intrinsicContentSize to get a good animatable height

also we want our floating label colour to be same of our shape and label font is set able

We are done. now we have a custom Animated label style input field. lets see a small demo of our code in action. Build and run the code

We will get this result hurrayy 🎉 🥂 isn’t it awesome 😎

You can get complete project on Github. feel free to fork, modify and make it better.

--

--