Framer, Prototype
Prototyping the Uber  Apple Watch App

Prototyping the Uber  Apple Watch App

When designing apps for the Apple Watch, one of the core principles is to keep it simple. The Uber app for Apple Watch is a prime example of this, having essentially just three screens: 

  1. Requesting an Uber
  2. Waiting for the request
  3. Letting you know your driver’s information and status 

When it comes to animation, the app displays a different loading animation on each screen, which made it an interesting prototype to recreate in Framer. 

Follow along this step-by-step Framer tutorial to create it for yourself. Here is the Framer prototype we’ll be creating:

Uber Apple Watch with Framer

To get started, download the Sketch file. I started with the Apple Watch GUI for Sketch from Meng To to create our screens in different artboards. When we import our designs into Framer, only grouped layers are accessible so pay close attention to how the layers are organized.


As an example, for our first screen, only the loading circle and the “Request” button are grouped. That’s because those are the only two layers we’ll be animating or interacting with on this screen. If you expand the loadingCircle group, you’ll see it only contains one layer. Even though it’s only one layer, we still need to put it in a group to use it in Framer. Now that we have our Sketch file ready, let’s move on to Framer.

The first thing we’ll do is clear the code editor and switch your device to an Apple Watch. Click the Viewer button in the top right corner of the toolbar and go to Device — Apple Watch 42mm — and select one of the many options.


With the Sketch file still open, click the Import button in the toolbar or use Command+I to bring up the Import dialog. Verify that the correct file is listed under the Sketch option and that the import button is active and import your design.


Framer will automatically add a comment and line of code to your prototype. We can rename our imported variable to something shorter, like uber.

We should see the Request screen in the preview pane on the right side. We can also see in the middle layer inspector panel that the other layers from the other screens were also imported but display in a lighter color since they aren’t visible. 


To create the loading pulse, we’ll create two animation objects. The first animation will scale the loadingCircle layer 10% larger using the scale property. To access any of our imported groups, we just type the imported file variable, followed by a period, and then the group name. In this case, we’ll use uber.loadingCircle to specify the layer to animate. We’ll also specify a time of 1.5 seconds for the pulse.

The second animation will scale the loadingCircle layer back to it’s original size, in the same 1.5 seconds.

We can now chain the animations so that they one starts when the other one ends.

To chain the animation, we’ll listen to the AnimationEnd event which is called when the animation reaches an end point. To listen to events, we specify the animation object to listen to, followed by a period, the word “on”, and then the event. 

When our pulseUp animation ends, we’ll want to start our pulseDown animation. We can start animation objects by using the start function. Since it’s a function, we need to add parenthesis after the name.

Alternatively, when our pulseDown animation ends, we’ll want to start our pulseUp animation.

All that’s left to do is start the animation.

We should now see our pulsing loading circle.


To transition to the next screen, we can create a Click event on the requestButton layer.

When we imported the Sketch file, only the first artboard is visible by default. To show the Requesting screen, we’ll need to set its visible property to true and hide the Request screen by setting its visible property to false.

If you try out the prototype now, the transition isn’t very smooth since it’s just instantly showing and hiding the screens. We can make it a little better by setting the Requesting screen’s opacity to .3 before we make it visible and then animating it to display with full opacity after. Rather than creating another animation object for this and telling it to start, we can just start the animation directly by typing the layer name, followed by a period and then animate and then specifying the properties to animate.

Here’s what your Framer prototyping should look like now:


On a real Apple Watch, tapping the request button would lead to a loading screen before displaying the next screen. 

The Requesting screen just displays a pulsing loading bar until a driver is confirmed. There’s also a cancel button that will take you back to the Request screen. For the purposes of this prototype, we won’t deal with the cancel button but you’re free to implement it as an exercise.

To create the loading pulse bar, we’ll need to set the bar, whose group is called requestingLoad in our Sketch file, to its starting position. We can do that by scaling down the layer horizontally using the scaleX property and giving it an opacity of 0.

We can then create an animation object for the loading bar. We’ll want to scale it back to it’s original size horizontally, and increase the opacity. Since we want to repeat this animation a few times, we can use the repeat option. 

We can go back to our requestButton click event and start the requesting pulse animation right after we transition to the screen.

Now we just have to experiment with the time and delay options until we have something we are happy with.

Here’s what our requesting an Uber screen looks like with the animation:


To transition to the next screen, we’ll need to specify a set number of times the loading pulse repeats. Every time the requestingPulse animation repeats, the AnimationEnd event is called so this is a perfect place to add our logic.

We’ll first create a variable, that we’ll call requestingCount that will hold our count and set it to 0 initially. We set it outside the block of code instead of inside the AnimationEnd event because if we set it inside it will reset to 0 each time, resulting in an infinite loop. 

In our AnimationEnd event, we’ll increase the counter each time it’s called. We can do that by setting the variable equal to itself plus one.

A shortcut to writing out the above statement is just to type the variable followed by two plus signs, which does the same thing. 

We can now add our logic that says to transition to the next screen once the requestingCount variable is equal to the number of times we want the animation to repeat. Let’s use three for this example.

When the count is three, we’ll do the same thing we did previously when transitioning from the Request screen to the Requesting . First we’ll set the opacity of the next screen, the enroute layer, to .3. We’ll set the visible property of the requesting layer to false and set the visible property of the enroute layer to true. We’ll then animate the screen’s opacity to one to make the transition more smooth.

Instead of keeping a counter and then transitioning to the next screen after a certain number of times, we could have done it another way and just transition after a set amount of seconds (hint: you can use Utils.delay to do this). Remember it’s a prototype so it doesn’t have to be perfect so use which ever way is faster or makes more sense to you.

Here’s the transition:


For the Uber enroute screen, we’ll need to rotate the circular progress bar, which is grouped in our Sketch file as enRouteProgress. We can do that by creating an animation object outside our AnimationEnd event block of code and setting the rotation property to a full 360 degrees. We’ll set the repeat option to a high number and also specify the time to do the full rotation. 

We can then start the animation right after we transition to the screen inside our if statement we wrote earlier.

If you view the prototype now, you’ll notice the rotation isn’t very smooth:


That’s because the default animation curve is an “ease-in-out” curve. We can fix this by specifying the curve for this animation to be linear.

Now our rotation animation looks more smooth and continuous:


This screen also has additional information if we scroll. If you look at the Sketch file for this artboard, you’ll notice it was structured so the content that is scrollable are all within the content folder and the page folder is masked.


We can make it scroll by creating a ScrollComponent using the wrap function on the content group from Sketch. 

We can specify for the screen to only scroll vertically by setting the scrollHorizontal property to false.

We should now be able to scroll the last screen in our prototype.


To make this Framer prototype a little more realistic, let’s make the car move. 

Create an animation object for the car to get to the corner and another one to turn. This is just a matter of trial and error of the x, y, and rotation values to get it to look like it’s going along the path.

We’ll create an animation chain event that will start moveCarLeft animation once the moveCarDown animation ends.

Then we’ll just call the moveCarDown animation after we start the enRouteRotate animation.

Our car now moves along the path. For the purposes of showing this here, I’ve made the time of each animation shorter to keep the GIF file size down:


Finally, let’s update the label after five seconds from “En Route” to “Arriving Now.” We’ll use the delay utility function which just takes in a number in seconds to wait before running the indented block of code underneath it. 

After five seconds, we’ll hide the current label and show the new one using the visible property.

Congratulations, we’ve just prototyped the Uber Apple Watch app in Framer.


You can see the prototype, download it and check out the full code here:

Uber Apple Watch with Framer

If you haven’t signed up for Uber yet, you can use my invite code, uberX$20FreeRide, and get a free ride up to $20.

Do you want to see a Framer prototype of an interaction from your favorite app? Let me know in the comment below or on Twitter (@kennycheny). If you want to be the first to know when I post new Framer tutorials, join the mailing list below.

Want more Framer content like this?

Share this Story

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

About Kenny Chen

Hi, I'm Kenny - a UX Designer from Los Angeles who believes that beautiful, subtle movement enhances the user experience and makes products more engaging, dynamic, and memorable. My goal with Prototyping with Framer is to help you design amazing interaction and animation prototypes.