Facebook Twitter Gplus LinkedIn RSS
 
 
Home » Blog » Navigation Bar with NativeControls in Cordova

Navigation Bar with NativeControls in Cordova

Published on May 7th, 2012 by in Blog, Cordova, Featured

I’ve written a few blog posts in the past about NativeControls, a plugin for Cordova/PhoneGap that let’s you use the Navigation Bar (the infamous app header) and the TabBar (the infamous app footer) in your web-based Apps. PhoneGap works as a layer between the native xCode and your javascript, giving you the responsiveness of a native app in your web app. On top of that, it feels really native, because it is native. In fact, it is one of my favorite ways to implement a simple UI in an app.

I’ve finally gotten around to updating the code on GitHub. The hide/show functions aren’t 100% right, but I got both portrait and landscape working. If someone wants to fork my code and fix some of the bugs, please feel free.

Setup is pretty simple. Grab the following files and add them to the plugin section of your project:

  • CDVNavigationBar.xib
  • CDVNavigationBarController.h
  • CDVNavigationBarController.m
  • NativeControls.h
  • NativeControls.m

Include the javascript files at the top of your index file. I’ve included them all to show that order matters:

1
2
3
<script type="text/javascript" charset="utf-8" src="js/controls.js"></script>
<script type="text/javascript" charset="utf-8" src="js/cordova-1.7.0.js"></script>
<script type="text/javascript" charset="utf-8" src="js/NativeControls.js"></script>
<script type="text/javascript" charset="utf-8" src="js/controls.js"></script>
<script type="text/javascript" charset="utf-8" src="js/cordova-1.7.0.js"></script>
<script type="text/javascript" charset="utf-8" src="js/NativeControls.js"></script>

You will need to edit the controls.js file for your own button settings. Use my example to guide you. You need to setup a few javascript listeners in your document.ready function.

1
2
3
4
$(document).ready( function() {
    document.addEventListener("deviceready", onDeviceReady, false);
    window.addEventListener("resize", orientationChange, false);
});
$(document).ready( function() {
    document.addEventListener("deviceready", onDeviceReady, false);
    window.addEventListener("resize", orientationChange, false);
});

Then in your deviceready function, you need to setup your NavigationBar (header) and TabBar (footer).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
function onDeviceReady() {
    newLoc = location.href.substring(0, location.href.lastIndexOf("/")+1);
    
    // Initializating TabBar
    nativeControls = window.plugins.nativeControls;
    nativeControls.createTabBar();
 
    // Back Button
  nativeControls.createTabBarItem(
    "page1",
    "Page 1",
    "www/images/pound.png",
    {"onSelect": function() {
        $.mobile.changePage( "#page1", { transition: 'reverse slide' } );
        nativeControls.setNavBarTitle("Page 1");
        nativeControls.selectTabBarItem("page1");
        selectedTabBarItem = "page1";
    }}
  );
  
  // Home tab
  nativeControls.createTabBarItem(
    "page2",
    "Page 2",
    "www/images/pound.png",
    {"onSelect": function() {
        if ( selectedTabBarItem == "page1" ) {
            $.mobile.changePage( "#page2", { transition: 'slide' } );
        } else {
            $.mobile.changePage( "#page2", { transition: 'reverse slide' } );        
        }        
        nativeControls.setNavBarTitle("Page 2");
        nativeControls.selectTabBarItem("page2");
        selectedTabBarItem = "page2";
    }}
  );
  
  // About tab
  nativeControls.createTabBarItem(
    "page3",
    "Page 3",
    "www/images/question.png",
    {"onSelect": function() {
        $.mobile.changePage( "#page3", { transition: 'slide' } );
        nativeControls.setNavBarTitle("Page 3");
        nativeControls.selectTabBarItem("page3");
        selectedTabBarItem = "page3";
    }}
  );
    // Compile the TabBar
    nativeControls.showTabBar();
    nativeControls.showTabBarItems("page1", "page2", "page3");
 
    selectedTabBarItem = "page1";
    nativeControls.selectTabBarItem("page1");
 
    // Setup NavBar
    nativeControls.createNavBar();
    nativeControls.setNavBarTitle("Page 1");
    
    nativeControls.setupLeftNavButton(
        "?",
        "",
        "onLeftNavButton"
    );
    
    //nativeControls.hideLeftNavButton();
 
    nativeControls.setupRightNavButton(
        "About",
        "",
        "onRightNavButton"
    );
 
    nativeControls.showNavBar();
}
function onDeviceReady() {
    newLoc = location.href.substring(0, location.href.lastIndexOf("/")+1);
    
    // Initializating TabBar
    nativeControls = window.plugins.nativeControls;
    nativeControls.createTabBar();

    // Back Button
  nativeControls.createTabBarItem(
    "page1",
    "Page 1",
    "www/images/pound.png",
    {"onSelect": function() {
        $.mobile.changePage( "#page1", { transition: 'reverse slide' } );
        nativeControls.setNavBarTitle("Page 1");
        nativeControls.selectTabBarItem("page1");
        selectedTabBarItem = "page1";
    }}
  );
  
  // Home tab
  nativeControls.createTabBarItem(
    "page2",
    "Page 2",
    "www/images/pound.png",
    {"onSelect": function() {
        if ( selectedTabBarItem == "page1" ) {
            $.mobile.changePage( "#page2", { transition: 'slide' } );
        } else {
            $.mobile.changePage( "#page2", { transition: 'reverse slide' } );        
        }        
        nativeControls.setNavBarTitle("Page 2");
        nativeControls.selectTabBarItem("page2");
        selectedTabBarItem = "page2";
    }}
  );
  
  // About tab
  nativeControls.createTabBarItem(
    "page3",
    "Page 3",
    "www/images/question.png",
    {"onSelect": function() {
        $.mobile.changePage( "#page3", { transition: 'slide' } );
        nativeControls.setNavBarTitle("Page 3");
        nativeControls.selectTabBarItem("page3");
        selectedTabBarItem = "page3";
    }}
  );
    // Compile the TabBar
    nativeControls.showTabBar();
    nativeControls.showTabBarItems("page1", "page2", "page3");

    selectedTabBarItem = "page1";
    nativeControls.selectTabBarItem("page1");

    // Setup NavBar
    nativeControls.createNavBar();
    nativeControls.setNavBarTitle("Page 1");
    
    nativeControls.setupLeftNavButton(
        "?",
        "",
        "onLeftNavButton"
    );
    
    //nativeControls.hideLeftNavButton();

    nativeControls.setupRightNavButton(
        "About",
        "",
        "onRightNavButton"
    );

    nativeControls.showNavBar();
}

Take the time to walk through the code and learn what is happening. First, we are setting up the TabBar (footer), and buttons. Then we are setting up the NavigationBar (header) and its two buttons. We will also need to create two functions for these buttons called “onLeftNavButton” and “onRightNavButton”.

1
2
3
4
5
6
7
function onLeftNavButton() {
    alert('Left Button Pressed');
}
 
function onRightNavButton() {
    alert('Right Button Pressed');
}
function onLeftNavButton() {
    alert('Left Button Pressed');
}

function onRightNavButton() {
    alert('Right Button Pressed');
}

Also, don’t forget to setup the function for orientation changes:

1
2
3
4
function orientationChange() {
    nativeControls = window.plugins.nativeControls;
    nativeControls.resizeTabBar();
}
function orientationChange() {
    nativeControls = window.plugins.nativeControls;
    nativeControls.resizeTabBar();
}

Last but not least, don’t forget to add “NativeControls” to your Cordova.plist file to initialize the plugin, and start up xCode. If you are lucky, you will see the top and bottom bars as shown in the screenshot. Download the demo and code over at GitHub.

Let me know how it works out for you!

About the Author: Sprawl

Stephen Russell is a Mobile App developer and all around IT geek that spends his days running data centers and his nights coding. This site is the go to place for all of zSprawl's work and the infamous development blog. In his free time, he enjoys tinkering with web code, playing video games, and otherwise plotting to take over the Internets.

 

80 Responses

  1. JonW

    I’m not sure if I’m doing something wrong here, but I have an issue since upgrading. Today I recreated my app in Xcode after installing Cordova 1.7.0 (previously running 1.5.0) and I removed the old NativeControls .h & .m files then replaced them with your latest release (plus all the other new files). I’m also referencing Cordova-1.7.0.js. When the app first launches, the bottom tab bar is in place as expected. As soon as I tap any of the tabs, it changes page but the tab bar vanishes and the whole page moves down leaving whitespace at the top of the app – the same size as the bottom tab bar was! I’m not calling a top nav bar, so do I even need this update?

    I have reverted to the previous version of NativeControls (still using Cordova 1.7.0) and it’s working fine again. Am I missing something?

    • You do not need the update if you aren’t using the top bar. In the meantime, I need to work on the resizing functions a bit. Thanks for the feedback.

      • Conchita BH

        Hi, im using the native controls plugin and everything works fine, but when i rotate the app (from portrait to landscape) the bar (i use top bar) doesnt resize

        if you have a fix i will appreciate your help

        thanks

  2. Mitch

    hi! congrats for the tutorial! i have a question for you..
    I’ve downloaded your code and i’m trying to do a very easy app.. the problem is that i can’t scroll down the page.
    please help;)
    Thanks!

  3. Chris

    is there anyway of changing navbar color and add background image?
    Great work btw

    • Sure! In xCode, edit the XIB file. Just click on the navbar, then on the right-side of the screen should be some properties that you can play with.

      • Chris

        Awsome should have checked there first. Thanks

      • Chris

        hi Again.I have changed the tabbar color! sweet.
        i cant get get the navbar color changed there are no settings in xcode that i can see and i have tried self.navigationController.navigationBar.tintColor = [UIColor orangeColor]; and all of the variants with no luck.

        any ideas please!!

  4. Chris

    Thanks for the reply. Nope i changed the bottom tabbar color with the following:
    > UIColor *myNewColor = UIColorFromRGB(0xCD2626);
    > tabBar = [UITabBar new];
    > [tabBar sizeToFit];
    > tabBar.delegate = self;
    > tabBar.multipleTouchEnabled = NO;
    > tabBar.autoresizesSubviews = YES;
    > tabBar.hidden = YES;
    > tabBar.userInteractionEnabled = YES;
    > tabBar.opaque = YES;
    > tabBar.tintColor = myNewColor;

    but cant seem to change the top navbar. grrrrr thanks again i have learnt heaps with your code.

  5. Vince

    Hi, does this work on Android? Can we customize colors and background outside XCode?
    Thanks!

  6. louminsk

    Hello
    Im beginning with dev iOS with the great Phonegap
    Thanks a lot for this great tutorial ,helps a lot.
    I m trying to get the label under the controls tabBar icon on two line for a specific request where 2 menus labels need to be set like this(there is 5 menus in the TabBar)
    I found how to increase the the height of the tabBar in NativeControls.m
    if(height == 0)
    {
    height = 65.0f;
    atBottom = YES;
    }

    -How i could customize the text box label for the TabBar this way ? (need to get the words corrects)
    -There is a way to set up the size of the icon box for TabBar?
    Thank in advance if someone can provide me

  7. Raul

    great article.

    one thing that i did in my app was to set the AutoHideSplashScreen to NO in Cordova.plist.

    then in deviceready, at the end of the function, i manually hide the spashscreen, like this:
    setTimeout(function() { cordova.exec(null, null, “SplashScreen”, “hide”, []); }, 0);

    This has the nice effect that when the main view is shown it already has the nav- and tab-bar.

    Otherwise you might see a flicker while the webview is initialized and the 2 bars are created.

  8. Vanda

    There seems to be some bugs when hiding and showing the tabbar is this the case or its just me?

  9. Pat

    Hi everyone-
    I seem to be having a slight issue with the navigation bar. When a new page is loaded, the page loads from the top of the screen, so that the navbar is covering the upper portion of the page. Is there any way to resolve this?

    Thanks!

    • Very odd… the viewport should only be the displayed window. However, my show/hide functions are very buggy right now, so perhaps that is the problem. I’m moving irl right now, but hope to jump back on this project soon.

    • Khaled

      Hi Pat, I am having your same problem, did you manage to fix that ?

  10. If I dont want title for my item,
    i put “null” and it is not working
      nativeControls.createTabBarItem (
                                                         “back”,
                                                         “Back”,
                                                         “www / images / Back_tablet.png”,
                                                         {“onSelect”: function () {
                                                         $. mobile.changePage (“# page1”, {transition: ‘reverse slide’});
                                                         nativeControls.setNavBarTitle (“Page 1”);
                                                         nativeControls.selectTabBarItem (“page1”);
                                                         selectedTabBarItem = “page1”;
                                                         }}
                                                         );

  11. Scott Riggle

    This work with the latest Cordova. I’ve tried every tutorial on native controls with not luck. New to Cordova and can’t get any plugin to work.. Did something break in 1.8+ with plugins?

    thanks, I’m new to cordova.

    Scott

  12. Daniel

    Is possible to add a badge on tab button?

  13. Manish

    I was trying to use the plugin. I downloaded the demo project and tried to run it. Its giving me compile error of “property ‘invokeString’ not found on object of type ‘MainViewcontroller'”

    I am using cordova 1.5.0 and jQuery 1.1.0

  14. Wang

    is there anyway to put a searchbox in the navbar ?
    Thanks.

    • While anything is possible, I did not code any way to do this.

      • Wang

        Thanks for your answer. I’m new to IOS so I do not have much experience. Just one more question: I try to add image to navbar button but it didn’t show up. This is my code:

        nativeControls.setupLeftNavButton(‘Back’, ‘www/images/back.png’, ‘onBack’)

        Button’s event works but the image didn’t show. Did I do something wrong ? Thanks.

        • georghill

          I have this question too, how to put images to Navbar buttons?

        • Perhaps you need the lead slash? “/www/images/back.png”?

          If that doesn’t work, compile it in xCode, then open up the file and get the exact path to the image. It should work. Your path must be wrong.

          • Wang

            I did try “/www/images/back.png” and it didn’t work too. In your example, you only change image for tabbar item, with navbar, you leave the field image blank. I try to change the tabbar image with the path ‘www/images/imagename.png’ and it works well, but it does not work for navbar. Can you pls try your code with custom image for navbar to check again. Thanks alot.

          • Sanjeev

            Is there any option to customize the left button to be a back button in xcode? I tried many ways available in various forums, but still cant able to find a solution.

  15. guy

    if I want to change the color of the nav bar ??
    tint and style .

    tnx.

  16. louminsk

    Hi Sprawl
    I use the original plugin nativecontrols perfectly working with Jquery and a multipage.
    Hide and show tabbar works great.
    On my application at the index the navigation tabbar is hide and after clicking on a Jquery list menu item, the tabbar is show and the correct tabbar menu item is select.
    When i return to the home page the native controls bars is hide again.
    I m happy of that except its only working inside a multiple page with jquery.
    But when try using it with some single page links , the navigation of the native doesnt work anymore.
    It just appear one but navigation of the tabbar doesnt work anymore and when return home page doesnt hide.
    Its something with Dom i imagine.But i m lost how use this
    (i use the function init to load the nativecontrols at the home page)

    Could help me a bit how use nativecontrols with single pages and jquery

    many thanks

  17. Wang

    Report problem: when I call function nativeControls.hideTabBar(), my page is slided up a little bit and being covered by the navbar and the page can not be scrolled anymore. Is this a bug or because of my bad code ?

  18. Adam

    Do you have a copy that will work pre-cordova ?
    I’m using 1.4.1 phonegap atm..

  19. Bojan

    Realy nice tutorial and well explained but i simply cant get it work.
    I’m using Cordova 1.9 and the last git:.. ios/nativecontrols plugin.

    I mean ChildBrowser works perfectly but native controls nothing. I cant fint anything on the web, do you know if they’ve changed anything in the last version of cordova/phonegap?

    Thanks man!

  20. Do you have any app examples?

    • You should be able to download the code above and run it with filler text. The px2em app that I have on the App Store uses this layout as well.

  21. Dalibor

    I tested your code and it works just fine, nice layout!
    But there is a problem with a scrolling in this app.
    When you put something in CONTENT div like listview, there is no scroll function at least not in simulator.
    Did you think about this?

  22. Christoph

    Hi Sprawl,

    thanks a lot for the plugin. NativeControls is really valuable to us and saved us a lot of time.

    We found one issue: Hiding the NavBar does work on the first screen but after resizing the first time, a blank rectangle apears at the top of the app and pushes the webview towards the end. The Tabbar slides out of sight, only the top 5 Pixel are still visible.

    The cause is variable topBar in NativeControls.m:resizeTabBar which is statically set to “44.0” but should have a value of 0 when NavBar is hidden. We were fixing topBar to “0.0” in our app and everything is working as expected from then on. Maybe you can add a switch in the next release that checks whether NavBar is hidden and set the value of topBar accordingly.

  23. Dalibor

    How to add ” Back ” button to topbar?
    I open .xib file and try to remove ” ? ” button and add Back button but i cant …
    Can u help with this?
    Thanks

  24. I have got this all working – I have also allowed scrolling (up and down) for longer content pages – the only problem is that when you scroll to the end of the page you can then go further which leaves a white space the same height as the bottom tab bar. Is there a reason for this?

    is there a minimum height for the content to be to stop this?

    See pic here:

  25. CordovaStarter

    Hi Sprawl,

    Thanks for the example. I am starting with Cordova.
    When i upload your www folder to phonegab it doesn’t show any toolbar.
    Do I need to upload a congif file for phonegab version or something?
    Thanks for your help!

  26. Brent

    If I don’t use an image icon on the footer navbar, it still has an empty space for that icon. How can I make it so it is just the text in the vertical middle of the tabbar without an icon?

  27. chuck

    Love this article, but I can’t get it working with the latest 2.1 release of Cordova. Any plans on updating your code – thx for the writeup.

  28. Gunnar

    Thanks for the plugin and coding.

    One question:
    How can I do a link index.html? E.g. I found the function onLeftButton():

    function onLeftNavButton() {
    window.location(“./index.html”);
    }

    window.location(“index.html”);, window.location(“(/)www/index.html”); window.location(“file://www/index.html”); and all window.location.href(…) don’t work either? Is there a trick?

    Thanks!

    PS: It is the first NavBar-Plugin that is working! Very cool!

  29. Ben

    Hey Sprawl, nice plugin!

    Is it possible to change the navbar for each side?

    E.g. the navbar looks like:

    index.html:

    title of navbar //nothinig else just title

    subpage.html:

    leftButton & title of navbar & rightButton

    Greetings,

    Ben

  30. Paul

    This works if I import it into xCode and with the updating of the build architecture and builds to the iPhone device. However, no orientation change. Is there supposed to be?

    Also, could not get it to work with Phonegap 2.1, don’t know why. I tried creating a new project in Phonegap and then just importing your www folder, updating script tags and installing your plugins. I’m not getting errors, but nothing is happening i.e. the controls don’t show up.

    Any tips how to upgrade? If not, I’ll just build with 1.8.1. Personally, I think the new updates are such a mess!

    Thanks for this plugin BTW!

    • Corey

      I am also having issues getting NativeControls working with Phonegap 2.1 Has anyone had any luck getting the plugin working?

  31. Mohammed Shaji Ahmed

    I have tried this code but running through issues, tab items are not getting called and display appropriate content. I am using Cordova 2.2.0 on OS x . I added alert to onSelect function for each tab this function is not getting called
    nativeControls.createTabBarItem(
    “page3”,
    “Page 3”,
    “www/images/question.png”,
    {“onSelect”: function() {
    alert(“page 3”);
    https://docs.google.com/open?id=0B-dtT5RyOEjcTXJtTFZ5bTRlZXM

  32. joey

    Hello Sprawl,the navbar not show with Cordova 2.3 but the footer tabbar,could you mind to help me for this?

  33. John Kiernan

    I downloaded your demo, took the WWW folder and renamed it and tried it with a browser in my localhost. As expected, it only showed the screen, but nothing else (I’m using WAMP).

    Then I zipped the whole folder (and sub-folders) and uploaded it to PhoneGap build and let it build and then downloaded it to both an iPad and an iPod Touch. Both showed exactly what the localhost did: the striped background and the “Thank You” note, but no controls of any kind. Is this what it’s supposed to show? Am I missing some action I am supposed to be doing (been years since I was an Apple guy).

    Thanks in advance for the reply.

    Again, I took your exact folder with no changes.

Leave a Reply to Wang Cancel reply

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

© 2012 zSprawl's zApps

Fork me on GitHub