UI Guideline specific titles (including iOS large titles) with react-native (Animated)
With the Release of iOS 11, Apple introduced large titles and added the specification to the Design Guidelines (https://developer.apple.com/ios/human-interface-guidelines/bars/navigation-bars/). After the first outcry the titles are meanwhile quite accepted and are used in more and more apps on iOS. Time to look at how to implement them in react-native.
We will create a “ViewWithTitle” component, which will be your container you can put a title and a child component. The ViewWithTitle then renders your page with large titles on iOS and standard titles on Android. It also animates the titles when the user scrolls.
Since I literally hate blog posts without detailed examples, you can check out the code of this post on Github (https://github.com/alexkuttig/react-native-view-with-title) or get the component via npm (npm i react-native-view-with-title).
Back to the implementation. There are two tricky parts regarding the titles.
- We want them to have the correct size on any device and meet specifications on both platforms.
- Large title should animate and change to standard titles when the user scrolls down on iOS.
The first part isn’t that hard. Its mainly about reading UI guidelines and write different cases… I wrote a little helper for that:
It returns me the heights for StatusBar, Header and the bottom padding value for iPhoneX, as well as vh and vw values for my SafeArea. With this values I can work in my ViewWithTitle component.
Next, we need to define how our component will be structured. We need an area for the header, as well as a container for the content.
You can see we have an outer container, where everything will contain everything, a title container, where the title will be placed and an inner container, where our content will be placed. We are using our DimensionsHelper for getting the height of the container. The missing render functions will be created in the next steps.
renderTitle 0.1:
First of all we have to do some Stylesheet based work again. Based on the different UI Guidelines, we write styles for iOS and Android titles.
No Animations, no iOS large titles here. We do need another thing first:
renderContentArea:
The structure is pretty simple. We use a ScrollView and put a full width view inside the ScrollView, where we then put the content. But for animating our title, we need to know when the ScrollView gets scrolled. So we add an onScroll function and bind the scroll value to our state.scrollY. This is important, since we use this value for animating our title in the next step!
renderTitle 1.0:
Since we only want to show the standard title on iOS, when the user scrolls the view, we have to do some animation magic via Animated API. We are just looking at the iOS part of our renderTitle function for the moment, because we don’t need any animation on Android here. We use our state.scrollY, which contains the scroll value of our ScrollView and interpolate it for an opacity and a border color. The border color change is needed, cause the title always stays on top (zIndex) of our large title, which we will create next.
Please note that we use extrapolate: ‘clamp’ to prevent the interpolate function from extrapolating the values.
renderIOSBigTitle:
Until now we only have an iOS title, which is hidden until the user scrolls. We’re going to change that now by adding a container with absolute positioning. This container is placed below (yIndex) our title container and on top (zIndex) of our content container. We also add two interpolates. One for the font size, which we want to get bigger when the user “overscrolls” the view. The second interpolate is used to move the container of the large title up (yIndex), so that it slips below (zIndex) our standard title container, when the user scrolls down. We also have to add some styles here.
In the end we only have to add some paddings here and there (content container) and: TADA! We’re done.
Here is the complete Code, including an implementation with optional FlatList usage instead of ScrollView (just give the component a data array and a renderItem function) and some length restrictions for the different titles, based on space and font size.
As stated before, all the code is available on GitHub (https://github.com/alexkuttig/react-native-view-with-title) and via npm (npm i react-native-view-with-title).
There is plenty of things that could be implemented based on this (Buttons, SearchField, PullToRefresh… … …). I’ll go on with this as soon as I find some free time…
In the meantime I appreciate any discussion and feedback!