Typing indicators are an essential part of any chat app. In a world where almost everything is live and information can travel across the globe in a matter of seconds, users expect chat apps to instantly notify them when the other user is typing a message.
There are a number of reasons you should always include a typing indicator in your app:
- It improves the user experience, making it clear that another user is typing
- It captures real-time activity, almost resembling real-life interactions
- It shows users’ engagement, helping to keep them engaged
In this article, you'll learn how to implement a typing indicator in your app - detecting when the sender is typing, sending that information to the receiver's device, and displaying that information in the form of a typing indicator.
Adding a Typing Indicator to Your iOS Chat App
Before you continue, make sure to sign up for a free CometChat account so you can follow along.
Add CometChat to Your App
You need to add CometChat as a dependency to your project using CocoaPods. In the sample app, this has already been done for you, so you don't need to do much.
Open your terminal, type cd, and drag the directory to your project inside the terminal window.
Run the command pod install in your terminal. Wait for the installation process to complete, and you're ready to move forward with the project. From this point on, you'll be working in the .xcworkspace project, and can ignore the .xcproj file.
Define Your App ID
To be able to use CometChat's service, sign up and create a free account. Your CometChat’s Dashboard should look like this:
You will need the following information to continue:
- App ID
- Auth key
If you don't already have a an AppConstants.swift file inside the folder App, select your project folder, then go to File > New > File…. Pick "Swift" as template for your new file, name the file AppConstants.swift, and select "Create".
Open your AppConstants.swift file and edit it to contain the following:
Replace the values inside the quotes with the corresponding values from your CometChat Dashboard.
Create a Typing Indicator View
With your app configured, it's time to programmatically create a typing indicator view. Open the typingIndicatorView.swift file, which is where you will store and define properties for your typing indicator view.
Make sure your file now looks like this:
Define the View's Properties
There are many different types of typing indicators. Common types include; plain text indicators, animated indicators, and indicators that combine animation and text. Placement is also variable; some appear at the bottom of the view and others appear on the navigation bar at the top, right where the sender's username is.
For this tutorial, you'll be making an animated typing indicator, as illustrated here.
In order to create a typing indicator which looks like this, you'll need to create two primary components: a gray view (to represent the bubble), and a horizontal stack view with three UIViews shaped into dots. The dots will be animated, with their opacity and scale increasing and decreasing.
This model was inspired by Marin Bencevic. In it, you'll create a private enumeration named Constants in which you can define the main properties of your view, such as:
- size, to define the height and width of the dot.
- scaleDuration, to define how long the animation should last.
- opacityAmount, to define how much the opacity should fluctuate to.
- scaleAmount, to define the scale to which the dots will transform.
- delayBetweenRepeats, to define how long until the animation repeats.
You will also need to create your stack view by declaring a private variable, named stack.
Edit your typing indicator view class to look like this:
You can copy-paste this into your code and change the parameters, such as size, scale, and duration, as desired.
Next, add the following function to make sure the view's size will adapt to the stack's content:
The next step will be to create a view for your typing indicator.
Create the Bubble View
In order to create the bubble view, you need to anticipate how much space the circles will occupy so you can make sure the bubble will be wide enough to fit the circles. You can use the following values:
- Constants.size will be your circles' width.
- The spacing between the circles will be set to 5.
- The spacing on the x-axis of the stack view will also be set to 5.
The following code will be used to calculate the width and height of your bubble:
The next thing you have to define is the color of the bubble. In the project's Assets section, create a new color set for your project:
Name the color set typingIndicatorBackground, and select the color for the light and dark view.
This is what the indicator will look like in dark mode:
To achieve the same look as the bubble in the pictures, you will need to do the following:
- define the height and width of the view using the calculation above
- set the corner radius to half the height of the entire view, so the edges are rounded.
- set the color to the one you just created: UIColor(named: "typingIndicatorBackground")
Create a function named makeBubble() that returns a UIView() with the width and height defined earlier, a custom background color of typingIndicatorBackground, and a corner radius of half the height of the bubble. You should end up with something like this:
Finally, add the function createConstraints(bubble:,stack:) to define the stack's position inside the bubble:
Remember to change the stack.centerXAnchor constant to half the value of content spacing inside the stack view. In this case, the spacing between the dots in the stack view was set to 5.
Create the Circles
Time to create the dots. Start by creating a function named makeDot(animationDelay: Double) that returns a UIView. This function will create one dot at a time, and you will call it three times to create three dots in a row.
To create this function, you'll do the following:
- Create a UIView the size of Constant.size, and set view.translatesAutoresizingMaskIntoConstraints to false
- Use Core Animation to create a Bézier path that draws a circle, from angle zero to 2π, with a radius value of Constant.size divided by two.
- Create the dot using CASShapeLayer():
You also need to animate the dots, using CABasicAnimation types transform.scale and opacity. The function should look like this:
Create the Typing Indicator
Time to put everything together into a single view. Create a function named createView(), add the bubble view and the stack view, then set translatesAutoresizingMaskIntoConstraints to false for each view:
Define your stack view to be horizontal, aligned to the center, and with a spacing value of 5:
Finally, use a for...in loop to create a dot three times, and add each one to the stack view. Use value i to define the animation delay and, once the loop is complete, add the subviews to its container view and call function createConstraints :
The result should be this:
Now uncomment createView() from init(), and you're done with the view. Time to implement it in the chat.
Connect the Typing Indicator with the Typing Notifications
CometChat handles the typing notifications in real time; this means that when the user starts or stops typing, the receiver's interface can immediately trigger the function and display a typing indicator view.
In the project, there's a file named cometChatMessageListExtension.swift. It will allow you to work on the chat message interface using a clean sheet. If you open it, you'll find both onTypingStarted and onTypingEnded methods, as well as if statements to differentiate between typing actions in a one-to-one chat and typing in a group chat:
These methods have been implemented for you.
Create a function named createTypingIndicator() in your cometChatMessageListExtension.swift file to add a typing indicator view to your view controller. The function should return a typingIndicatorView that's invisible until a typing notification is received, and appears just above the typing text view in the view controller.
Copy-paste this in to your code:
With this method, you'll be able to add a typing indicator view to your view controller. In your project, there is a typingIndicatorBubble property of type typingIndicatorView in the CometChatMessageList view controller. This means that you can assign the result of this method to typingIndicatorBubble, and you will be able to access it anywhere across your view controller.
Now that the typing indicator is ready, you need a method to trigger the typing indicator view to become visible, raise the bottom constraint of the table view so the typing indicator doesn't overlap the most recent message in the chat, and scroll the table view to the bottom automatically so the last message isn't cropped when the bottom constraint is raised.
The easiest way to do this is to add a Boolean parameter to the function and define a different behavior, depending on whether the typing indicator is showing:
Finally, handle the typing notification using showTypingIndicator(_bool:) by adding it in onTypingStarted and onTypingEnded as follows:
Build your project on two different devices or simulators, log in with different accounts, and start typing to see your new typing indicator at work.
Handle Group Chats Typing Indicator
The typing indicator looks perfect now, but what about group chats? How do you know who is typing?
One solution would be to add the avatar of the user that is typing in a stack view that will appear next to the typing indicator. Here is a representation:
To achieve this, you will need to create a stack view that will go next to the typing indicator bubble. The stack should be vertically aligned with and the same height as the bubble view, on a horizontal axis.
Copy-paste the following method in your code:
You now need to populate the stack view with rounded image views displaying the avatar of the user or users who are typing. CometChat stores the data of the avatar as a url, so you will need a method that will fetch the image data and display it in the UIImageView:
Add the following statement in viewDidLoad() to keep track of the users that are currently typing:
Replace the comment "// show typing indicator in group conversations" inside your CometChatMessageList class, with the following function to display a typing indicator with the avatar of the user that is typing:
Let's break down what you just did with this method:
- You tagged each avatar, so you can remove it when the user stops typing or sends the message.
- You checked that the avatar exists and is not already in the stack view.
- You added the new avatar at the beginning (left side) of the stack (position 0).
This will make it easy to track each avatar and remove it from the stack. Next, replace the comment "// hide typing indicator in group conversations" with the following function, and you're done:
Once you build your project, you'll have typing indicators fully implemented in your chat application.
Benefits of CometChat
With CometChat's robust offering of SDKs and APIs, adding even advanced chat functionality like typing indicators can be added to your application easily. CometChat handles all of the heavy lifting, allowing you to add a full-featured chat system to your application in hours instead of weeks, freeing up your engineers to focus on your core business concerns.
Extensions allow you to add even more functionality to your application, such as end-to-end encryption, media previews, polls, multiple types of notifications, and stickers, gifs, and emoji reactions. You can even create collaborative documents, or livestream an event, and it still only takes minutes to implement.
You can download the final version of this project from GitHub to see all the code in one place.
Building a typing indicator view can definitely be challenging. It is especially hard and time-consuming to handle the typing notification between devices. Luckily, CometChat can handle that for you in the background so you only have to take care of the user interface. Start building with CometChat today, and see how quickly you get a fully featured, in-app messaging experience up and running on your site.