Me!

TJ VanToll

NativeScript Quick Tip: Managing iOS Navigation Bars

| Comments

I’ve gotten a whole lot of questions about adding navigation bars to NativeScript iOS apps, so I thought I’d write a quick post about it.

The NativeScript 1.2 release included an <ActionBar> UI component that makes the functionality this article describes possible without needing to know the iOS specifics.

Showing the navigation bar with a title

Let’s say you have the following simple NativeScript app:

<!-- main-page.xml -->
<Page loaded="pageLoaded"></Page>
// main-page.js
function pageLoaded(args) {
    var page = args.object;
}

By default this app does not show a navigation bar, because that’s the default iOS behavior as well. Here’s how you can alter your JavaScript to show the navigation bar on iOS with a title:

// main-page.js
var frameModule = require("ui/frame");

exports.pageLoaded = function(args) {
	var page = args.object;

	// Make sure we're on iOS before making iOS-specific changes
	if (page.ios) {

		// Tell the frame module that the navigation bar should always display
		frameModule.topmost().ios.navBarVisibility = "always";

		// Change the UIViewController's title property
		page.ios.title = "My Awesome App";

		// Get access to the native iOS UINavigationController
		var controller = frameModule.topmost().ios.controller;

		// Call the UINavigationController's setNavigationBarHidden method
		controller.navigationBarHidden = false;
	}
};

Here’s what this looks like:

All that you’re doing here is invoking iOS APIs using the NativeScript runtime. page.ios.title sets the UIViewController’s title property; controller.navigationBarHidden calls the UINavigationController’s setNavigationBarHidden method. That’s it.

This means that in NativeScript you’re not limited to what NativeScript provides; if an API exists in iOS or Android you can just call it. Let’s look at one more example.

Changing the navigation bar’s color

Let’s say you want to change your navigation bar’s background color. Here’s how you make the navigation bar red:

// main-page.js
var frameModule = require("ui/frame");

exports.pageLoaded = function(args) {
	var page = args.object;

	// Make sure we're on iOS before making iOS-specific changes
	if (page.ios) {

		// Tell the frame module that the navigation bar should always display
		frameModule.topmost().ios.navBarVisibility = "always";

		// Change the UIViewController's title property
		page.ios.title = "My Awesome App";

		// Get access to the native iOS UINavigationController
		var controller = frameModule.topmost().ios.controller;

		// Access the UINavigationBar and change its barTintColorProperty
		controller.navigationBar.barTintColor = UIColor.redColor();

		// Call the UINavigationController's setNavigationBarHidden method
		controller.navigationBarHidden = false;
	}
};

Here’s what that red navigation bar looks like:

Again, all that you’re doing here is invoking iOS APIs with the NativeScript runtime. controller.navigationBar gets a reference to the app’s UINavigationBar, and navigationBar.barTintColor = UIColor.redColor() changes its barTintColor property.

What else can you do?

Anything iOS allows you to do. Seriously. Obviously when you make these very iOS-specific changes some knowledge of iOS is required, and some knowledge of how NativeScript handles marshalling between Objective-C and JavaScript certainly helps, but I still think it’s cool that you can access these native APIs so easily—in JavaScript even!

The appeal of NativeScript is that over time more and more of these common tasks are going to be abstracted into platform-agnostic modules so that you don’t have to know the platform-specific details. There are already dozen of modules out there, and new ones are being added with each release.

Comments