Reproducing Snapchat’s Navigation on iOS — Part 3

In Parts 1 and 2 of this tutorial we focused on gesture-based navigation. It’s time to give our app the final touches and add a second way to navigate.

Time give our app the final touches

Generally we have three buttons at the bottom. It doesn’t sound unusual, right? We’ve got it in UITabBar, so what’s the big deal? By tapping, we’re redirecting user to the proper controller and… that’s the end of the similarities. The buttons have custom height, they change position while changing scroll offset in both axis, they have animated transparency and what is more important — there aren’t covering part of screen, the app is focused on providing full screen UX without navigation and tab bar.

Let’s start our work by creating some Layout constants and adding a container for the buttons controller.

Now that we have the container, we can focus on the buttons controller.

Buttons should obviously communicate with the main controller. Add buttonsController.delegate = self and implement:

There isn’t much to explain here; by tapping the button we’ll change scrollView content offset with animation.

Now add new constants values to Layout enum:

And add buttons factory method:

Finally, we can go to the buttons controller.

Add the needed variables, then setup UI for the buttons.

Now we can take advantage of scroll view, which we decided to choose in first part of this tutorial. In ButtonsController we can add a method which animates button with offset changes.

We simply calculated the space between buttons and once again, we’ll multiply it by a value from the range, now (-1 -> 1). The central button will now change its position on the y-axis, the other two on the x-axis. Our button controller is done, so we can go back to main view controller to calculate offset and animate the buttons. Add scrollView.delegate = self and:

The app can be now be navigated through the buttons, but changing the view from left to right (or opposite side) causes some unwanted animation — the buttons should stay still. We can eliminate this by adding a new variable:

This means that every time the center view is visible, or we are entering it from the right or left panel, we will see the animation.

This should prevent animations enabling every time the user decides to navigate via gestures.

One more thing — while browsing through views in Snapchat, the background color changes from one into another with a smooth transition. We’ve got almost everything we need to implement it.

What kind of logic is used here?

UIColor can be described as a RGBA elements, which we are decomposing into a touple of CGFloat values. Why are we checking the number of components and comparing it to two?

Colors in apps from version iOS 10 and above are created in two spaces, UIExtendedGrayColorSpace and UIExtendedSRGBColorSpace.

UIExtendedGrayColorSpace is represented by 2 components, we need them to calculate the transition from UIColor.clear

UIExtendedSRGBColorSpace is represented by 4 components. We are using it for every other color

2. This method calculates each color’s basic components combining start and end color values multiplied by offset values.

We can use it in scrollViewDidScroll(_:) delegate.

We are predicting the color by checking the scroll direction. If we want to animate this transition, it means that the center view will be visible. If it will be visible, we need to set as a start color .clear. In this case center view should be hidden all the time — we can set two colors without checking direction.

And that’s all you need to build Snapchat’s navigation on your own. After a bit of styling, our app should looks like the animation below:

I hope you enjoyed this tutorial, and if you have any questions, feel free to contact me, or comment!

You can also check out the implementation on GitHub: https://github.com/arturchabera/ios-snapchat-navigation