Translucent NativeScript Tabs in iOS

In this NativeScript tutorial, I'll share with you a technique on getting a beautiful, dark translucent tab bar in iOS in your NativeScript…

Translucent NativeScript Tabs in iOS poster

Take control of your career. Build JavaScript mobile apps.

ng atlanta

Catch Dave Coffin, Nathan Walker, and Alex Ziskind at ngAtlanta in February 2020 for an advanced NativeScript with Angular workshop called  Breathe life into mobile UX with solid architecture lessons. You can register now and take your NativeScript skills up a notch.  Register here.

In this NativeScript tutorial, I'll share with you a technique on getting a beautiful, dark translucent tab bar in iOS in your NativeScript apps.


TL;DR

If you prefer watching a video of the tutorial, then here you go:




Introduction

If you take a look at the iOS Trailers app, you will notice a dark translucent tab bar that shows the content underneath as you scroll through the movie covers.


iOS Trailers app


You can't get this effect out-of-the-box with NativeScript, but I am going to show you a workaround that will get us the same effect in a NativeScript iOS app.

Let's Jump Right In

For the demo app, I created a NativeScript Angular application from the Tabs template, which gives us an app with a Tab View set up with some pre-configured routes.


Starter app


The default Tab View is actually translucent, but it's hard to see that because it's the same color as the background of the ListView underneath.


Let's make the app a bit more interesting by replacing the Items ListView with images of Sunsets:


<!-- home.component.html -->

<GridLayout>
  <ScrollView>
    <StackLayout>
      <Image src="https://en.es-static.us/upl/2018/06/sun-pillar-6-25-2018-Peter-Gipson-sq.jpg" height="200" stretch="aspectFill"></Image>
      <Image src="https://live.staticflickr.com/4689/38703929614_f06412345c_b.jpg" height="200" stretch="aspectFill"></Image>
      <Image src="https://www.visitcalifornia.com/sites/default/files/VC_LaJollaSunsets_RF_168579929_1280x640_0.jpg" height="200" stretch="aspectFill"></Image>
      <Image src="https://www.iamexpat.nl/sites/default/files/styles/article--full/public/windmills-at-beautiful-sunrise-netherlands.jpg?itok=u2M9p2MF" height="200" stretch="aspectFill"></Image>
      <Image src="https://en.es-static.us/upl/2018/06/sun-pillar-6-25-2018-Peter-Gipson-sq.jpg" height="200" stretch="aspectFill"></Image>
    </StackLayout>
  </ScrollView>
</GridLayout>

If you scroll through the images, you will see them showing beneath the Tab View.


Light translucent tab bar


The Tab Bar is translucent, but that's not the effect we are going for, we want a dark translucent tab bar, similar to the one in the iOS Trailers app.


You might think that you can get the same effect by changing the tab bar's color to black with CSS:


/* app.component.ios.scss */

@import 'app.component';

// Place any CSS rules you want to apply only on IOS here
TabView {
  tab-background-color: black;
  selected-tab-text-color: $item-active-color;
}

The effect you get from that isn't really what we are going for. The dark tab bar's translucency is hardly noticeable, and you don't get the nice blur effect on the content beneath it.


Black tab bar


Instead of getting a dark tab bar by setting its style in CSS, we are going to access the native iOS Tab Bar component and change its style.


Remember to remove the tab-background-color: black from your CSS file.


In app.component.html, add a loaded event to the TabView.


<!-- app.component.html -->

<TabView androidTabsPosition="bottom" (loaded)="tabViewLoaded($event)">
  <page-router-outlet
    *tabItem="{title: 'Home', iconSource: getIconSource('home')}"
    name="homeTab">
  </page-router-outlet>
  
  <page-router-outlet
    *tabItem="{title: 'Browse', iconSource: getIconSource('browse')}"
    name="browseTab">
  </page-router-outlet>
  
  <page-router-outlet
    *tabItem="{title: 'Search', iconSource: getIconSource('search')}"
    name="searchTab">
  </page-router-outlet>
</TabView>

Then add the tabViewLoaded() handler to the code file app.component.ts.


// app.component.ts

import { Component, OnInit } from "@angular/core";
import { isAndroid, isIOS } from "tns-core-modules/platform";
import { TabView } from "tns-core-modules/ui/tab-view/tab-view";

@Component({
  selector: "ns-app",
  moduleId: module.id,
  templateUrl: "app.component.html",
  styleUrl: ["./app.component.scss"]
})

export class AppComponent implements OnInit {
  constructor() {
    // Use the component constructor to inject providers.
  }
  
  ngOnInit(): void {
    // Init your component properties here.
  }
  
  getIconSource(icon: string): string {
    const iconPrefix = isAndroid ? "res://" : "res://tabIcons/";
    
    return iconPrefix + icon;
  }
  
  tabViewLoaded(args) {
    const tabView: TabView = args.object;
    
    if (isIOS) {
      let tabBarController: UITabBarController = tabView.ios;
      tabBarController.tabBar.barStyle = UIBarStyle.Black;
    }
  }
}

In the above code, we first grab a reference to the TabView, then we ensure that the code that follows only runs on iOS. On Android, it will crash.


We get a reference to the underlying UITabBarController and the tab bar view associated with this controller. We then set the tab bar view's barStyle property. This property determines whether the tab bar uses a dark or light visual style when no background image or tint color is specified. You specify the style with UIBarStyle—an enum. You can check here for a list of possible values.


If you want IntelliSense to be active when using native iOS and Android APIs, you should set up NativeScript platform declarations (tns-platform-declarations). Here is a tutorial on how to do that.


If you run the app, you will now see the dark translucent tab bar, similar to the one in the iOS Trailers app.


Dark translucent tab bar


That brings us to the end of this quick tutorial. I hope it taught you a thing or two.
We are creating a series of iOS-focused NativeScript tutorials, so look out for those. Here are some of the posts in the series. We'll be adding to the collection in the coming weeks.



If you have any questions or comments about the tutorial, leave them in the comments below, or get in touch with me on Twitter @davecoffin or Alex @digitalix.


For more video tutorials about NativeScript, check out the courses on NativeScripting.com. You'll find courses that cover all flavors of NativeScript (Core, Angular and Vue) and that cater to different levels of experience, whether you are just beginning your journey in the NativeScript world or you have some experience with NativeScript and are looking to level up.


Dave is an accomplished NativeScript developer, a Progress Developer Expert for NativeScript, a full stack web developer, and a passion for creating intuitive and beautiful digital experiences.

Did you enjoy this? Share it!

Take control of your career. Build JavaScript mobile apps.