Share Your Code

Tab Bar

Posted by Gilbert, Posted on September 8, 2010, Last updated October 19, 2010

Create a tab bar that will allow you to switch screens within your app.


Simply include the viewController.lua file in your main.lua file. Create screen1.lua, screen2.lua, etc. files for each screen. Then use the code below to add a tab bar that will allow you to switch between the screens.

Download an example of the code for the tab bar:
http://bitbucket.org/gilbert/view-controller-library/src/tip/TabBar/

Usage

1
2
3
4
5
        tabBar = viewController.newTabBar{
                        background = "tabBar.png",      --tab bar background
                        tabs = {"Play", "News", "About"}, --names to appear under each tab icon
                        onRelease = showScreen  --function to execute when pressed
                }

Optional parameters for tab bar images:
default = {"tabBtn-1.png", "tabBtn-2.png", "tabBtn-3.png", }
over = {"tabBtn-1_over.png", "tabBtn-2_over.png", "tabBtn-3_over.png", }

If not specified, the app will look for tab1.png, tab2.png, etc... and tab1_over.png, tab2_over.png, etc... in your build folder.

Code

The code below should be in a file named viewController.lua and placed in the build folder with your main.lua file.

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
-- viewController.lua
-- Version 1.1
 
module(..., package.seeall)
 
--initial values
local screenW, screenH = display.contentWidth, display.contentHeight
local viewableScreenW, viewableScreenH = display.viewableContentWidth, display.viewableContentHeight
local screenOffsetW, screenOffsetH = display.contentWidth -  display.viewableContentWidth, display.contentHeight - display.viewableContentHeight
 
function newTabBar(params)
        local background = params.background
        local tabs = params.tabs
        local default = params.default
        local over = params.over
        local onRelease = params.onRelease
        local font = params.font or "Helvetica"
        local size = params.size or 11
        local offset = params.offset or 14
 
        local tabBar = display.newGroup()
        
        local tabBG
        if background then
                tabBG = display.newImage(background, 0, 0)
                tabBar:insert(tabBG)
        end
 
        --check for tab and tab over images specified by the user
        if not default then 
                --if no tab images, use tab1.png, tab2.png, etc.
                default = {}
                for i=1, #tabs do
                        table.insert(default, "tab".. i ..".png")        
                end
        end
        if not over then 
                --if no tab over images, use tab1_over.png, tab2_over.png, etc.
                over = {}
                for i=1, #tabs do
                        table.insert(over, "tab".. i .."_over.png")      
                end
        end
                        
        --create the tabs
        local textSize = 11
        for i=1, #tabs do 
                local tab = ui.newButton{ 
                                default = default[i], 
                                over = over[i], 
                                onRelease = onRelease,
                                text = tabs[i],
                                font = font,
                                size = size,
                                offset = offset
                        }
                tabBar:insert(tab)
                
                local numberOfTabs = #tabs
                local tabButtonWidth = tab.width
                local totalButtonWidth = tabButtonWidth * numberOfTabs
                local tabSpacing = (screenW - totalButtonWidth)/(numberOfTabs+1)
 
                tab.x = math.floor(tab.width*(i-1) + tabSpacing * i + tab.width*0.5)
                if tabBG then tab.y = math.floor(tabBG.height*0.5) else tab.y = math.floor(tab.height*0.5) end
 
                tab.id = i
        end
 
        tabBar.y = math.floor(screenH - tabBar.height - display.screenOriginY)
        tabBar.x = 0
 
        tabBar.selected = function(target)
                        if not target then target = tabBar[2] end
                        if tabBar.highlight then tabBar:remove(tabBar.highlight) end
                        
                        local highlight = ui.newButton{ 
                                        default = over[target.id], 
                                        over = default[target.id], 
                                        onRelease = onRelease,
                                        text = tabs[target.id],
                                        font = font,
                                        size = size,
                                        offset = offset
                                }
                        highlight.id = target.id
                        tabBar:insert(highlight)
                        
                        highlight.x = target.x
                        highlight.y = target.y 
 
                        tabBar.highlight = highlight
        end
                
        return tabBar
end

Compatibility: 
Corona 2.0

Replies

alarew
User offline. Last seen 1 week 1 day ago. Offline
Joined: 10 Feb 2010

Can anyone quickly explain to me why at the screen levels (screen1, screen2, screen3) it must be enclose in a:

function new()
local g = display.newGroup()

content here

function g:cleanUp()
g:removeSelf()
end

return g
end

I dont understand why this is neccesary. I am trying to put content in like the list code from another code example and I am not sure what is wrong with it. A simple description of the function requirement would help. I dont get why that is necessary.

moboli
User offline. Last seen 2 years 7 weeks ago. Offline
Joined: 23 Jan 2011

Hi Gilbert,
Thanks for posting this code. It's very useful. But is there an easy way to specify that you don't want any button text?

JonStodle
User offline. Last seen 3 years 16 weeks ago. Offline
Joined: 5 Feb 2011

Isn't it possible to just use an empty string to accomplish this?

1
2
3
4
5
 tabBar = viewController.newTabBar{
                        background = "tabBar.png",      --tab bar background
                        tabs = {"", "", ""}, --no names to appear under each tab icon(?)
                        onRelease = showScreen  --function to execute when pressed
                }

sjanousek
User offline. Last seen 2 years 46 weeks ago. Offline
Joined: 21 Jun 2010

It would be helpful to see an example of how multiple UI's can be used together. This is usually how complex applications are built :) ... say a tabBar and slideView mixed together, etc, not just separate code examples.

Any examples such as this?

moboli
User offline. Last seen 2 years 7 weeks ago. Offline
Joined: 23 Jan 2011

Hi Jon,
Thanks for your suggestion. I did't even think to try that. I was busy adding a boolean to specify whether or not to display button text. Duh!

clonew09
User offline. Last seen 2 years 33 weeks ago. Offline
Joined: 17 Jan 2011

Hi, I am new with Corona and lua. I am a complete and total noob. I was wondering what the onRelease = showScreen is, and how it works. I am also wondering how to adapt the script for my needs, because I am at a loss on how to make a start up page, and i've tried the sample code.Please help!

Francis Chen
User offline. Last seen 2 years 3 weeks ago. Offline
Joined: 19 Jan 2011

Hi,
Did anyone have example for tab view + table view. So that each tab will have different scrolling table inside.

Thank you!

dl1606
User offline. Last seen 1 year 16 weeks ago. Offline
Joined: 13 Feb 2011

Hi,
Tanks for post the Code.
But i tried to define 3 different screens with Buttons and it won't work . Does Anyone have an idea how i can get this To work ?

Daniel

Francis Chen
User offline. Last seen 2 years 3 weeks ago. Offline
Joined: 19 Jan 2011

The code here with 3 different screen files. Screen1.lua.....screen3.lua
Each file defined as module here.
I think you better define your screen as modules.

nesavoth
User offline. Last seen 3 years 6 weeks ago. Offline
Joined: 8 Jul 2011

Hey thanks for posting this code... May someone please direct me to what I need to change to make 5 tabButtons? I'm struggling to comprehend lua programming before my deadline...

Thanks,
Nate

nesavoth
User offline. Last seen 3 years 6 weeks ago. Offline
Joined: 8 Jul 2011

Nevermind. I figured it out... interesting...

robmiracle
User offline. Last seen 26 weeks 5 days ago. Offline
Joined: 18 Jan 2011

Thanks for some great code. I have this working with the new Widget library to load tableViews and such on the various tabs.

However I am having one problem (well 2). On the simulator it looks great. On my iPhone 4, I'm getting about a 4 pixel white line (the color of my background) below the bar. Secondly the fonts are not showing at size 11, but more like 18.

I'm using "Helvetica" so I know the font is there.

Any ideas?

Thanks
Rob

robmiracle
User offline. Last seen 26 weeks 5 days ago. Offline
Joined: 18 Jan 2011

I solved the problem by detecting if I'm a retina display and scaling the fonts back by modifiying the ui.lua file

photiscta
User offline. Last seen 4 days 10 hours ago. Offline
Joined: 16 Feb 2011

Which is the best way to pass variables to another tab?
I am using the _G and also through a "settings.lua" module.
Is there any other way (better or worst)?

monforte
User offline. Last seen 41 weeks 2 days ago. Offline
Joined: 13 Sep 2010

Background of Tab Bar
I modified the viewController.lua to work with different screen form factors. On line 43 I chnged the code to x scale the background to fit the screen.

1
2
3
4
5
6
7
        local tabBG
        if background then
                tabBG = display.newImage(background, 0, 0)
                tabBG.xScale = display.contentWidth/tabBG.width
                tabBG.x = display.contentWidth/2
                tabBar:insert(tabBG)
        end

Hope it will be usefull for other developers.

cxroh
User offline. Last seen 15 weeks 5 days ago. Offline
Joined: 16 Jan 2011

Can Tab Bar function as one of the scenes within the scope of the Director app? I have some scenes that use regular buttons, and others that need a tab bar approach. I want to press a button from one screen and transition to a tab bar set of screens, then be able to go back to the calling screens. I am using Director.lua to facilitate changing scenes.

doga.tuncyuz
User offline. Last seen 2 years 35 weeks ago. Offline
Joined: 19 Dec 2011

did you find an answer for your question mate? I'm doing exactly the same using tabview and scrollview examples but couldn't fit them perfectly

topnotch374
User offline. Last seen 1 year 30 weeks ago. Offline
Joined: 1 Feb 2012

Hi, would you mind sharing where in the code you can find the number of tabButtons? I wanted to create 4 tabButtons but just can't figure it out. Thanks in advance

robmiracle
User offline. Last seen 26 weeks 5 days ago. Offline
Joined: 18 Jan 2011

You don't have to specify a number. You create a table with information for each button. The number of table entries determines the number of buttons:

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
local tabButtons = {
    {
        label = "Podcasts",
        up = "images/tab2.png",
        down = "images/tab2_over.png",
        width = 32,
        height = 32,
        onPress = showScreen1,
        selected = true
    },
    {
        label = "News",
        up = "images/tab1.png",
        down = "images/tab1_over.png",
        width = 32,
        height = 32,
        onPress = showScreen2,
    },
    {
        label = "Reviews",
        up = "images/tab3.png",
        down = "images/tab3_over.png",
        width = 32,
        height = 32,
        onPress = showScreen3,
    },
    {
        label = "Live",
        up = "images/tab4.png",
        down = "images/tab4_over.png",
        width = 32,
        height = 32,
        onPress = showScreen4,
    }
}

topnotch374
User offline. Last seen 1 year 30 weeks ago. Offline
Joined: 1 Feb 2012

Hi Robmiracle, thanks so much for the reply however I'm still very lost right so I hope you bare with me here. First, where should I add the table to? main.lua or ui.lua or viewController.lua? Been looking at your code but I just can't figure it out... so hard to be reading something that you can't understand... anyways... thank you so much for the time :)

robmiracle
User offline. Last seen 26 weeks 5 days ago. Offline
Joined: 18 Jan 2011

Here is the full main.lua that sets up a tabBar controller.

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
local json = require "json"
 
local director = require("director")
local widget = require("widget")
widget.setTheme("theme_ios")
 
local ui = require("ui")
 
local pageTitle = "App Name"
titleText = nil
 
local mainGroup = display.newGroup()
mainGroup:insert(director.directorView)
 
local function showScreen1()
    director:changeScene("feed")
end
 
local function showScreen2()
    director:changeScene("feed2")
end
 
local function showScreen3()
    director:changeScene("feed3")
end
 
local function showScreen4()
    director:changeScene("feed4")
end
 
math.randomseed(os.time())
 
local bg = display.newImageRect("images/background.png",320,480)
bg.x = display.contentWidth / 2
bg.y = display.contentHeight / 2
 
 
-- create a gradient for the top-half of the toolbar
local toolbarGradient = graphics.newGradient({93, 51, 1, 255},  {141, 99, 49, 255 }, "down" )
 
-- create toolbar to go at the top of the screen
local titleBar = widget.newTabBar{
    top = display.statusBarHeight,
    background="images/gradient.png",
    height = 44
}
 
 
-- create embossed text to go above toolbar
titleText = display.newEmbossedText( "YourAppName", 0, 0, "Helvetica", 20 )
titleText:setTextColor( 239, 205, 41 )
titleText:setReferencePoint( display.CenterReferencePoint )
titleText.x = display.contentWidth * 0.5
titleText.y = titleBar.height * 0.5 + 22
 
--Create a group that contains the screens beneath the tab bar
 
local tabButtons = {
    {
        label = "Podcasts",
        up = "images/tab2.png",
        down = "images/tab2_over.png",
        width = 32,
        height = 32,
        onPress = showScreen1,
        selected = true
    },
    {
        label = "News",
        up = "images/tab1.png",
        down = "images/tab1_over.png",
        width = 32,
        height = 32,
        onPress = showScreen2,
    },
    {
        label = "Reviews",
        up = "images/tab3.png",
        down = "images/tab3_over.png",
        width = 32,
        height = 32,
        onPress = showScreen3,
    },
    {
        label = "Live",
        up = "images/tab4.png",
        down = "images/tab4_over.png",
        width = 32,
        height = 32,
        onPress = showScreen4,
    }
}
 
local tabBar = widget.newTabBar{
    top =  display.contentHeight - 50,
    buttons = tabButtons,
    height = 50,
    background="images/gradient.png"
}
 
mainGroup:toFront()
showScreen1()

robmiracle
User offline. Last seen 26 weeks 5 days ago. Offline
Joined: 18 Jan 2011

You do not need the external file. Corona has this as part of their widget library, so the version in the community code isn't needed any more.

topnotch374
User offline. Last seen 1 year 30 weeks ago. Offline
Joined: 1 Feb 2012

Hi Robmiracle, thank you so much for taking extra time on this... really appreciate it. Honestly I'm still lost here but I guess it's part of the learning process. I will look more into this but once again THANK YOU so much!!!

topnotch374
User offline. Last seen 1 year 30 weeks ago. Offline
Joined: 1 Feb 2012

Hi Robmiracle, I've been trying to get the code to work but unfortunately still can't figure it out.

I'm kinda confuse on the images, do I need to create this images or it's in the library already?

I included in my project files the following:
ui.lua
director.lua
config.lua
main.lua (I used your code above)
theme_ios.lua
widget_ios folder

every time I run the code it gives my error messages... kinda frustrated here already.

Just wondering may be you may have a working project using tabs that you can share with me? It would really be awesome... Thanks in advance.

robmiracle
User offline. Last seen 26 weeks 5 days ago. Offline
Joined: 18 Jan 2011

If it's an image listed in my code, you will need to create it.

Here's the problem with working projects. They are functioning apps in the App store and I'm not inclined to share my entire projects. I doubt you would clone my project, but there are plenty of examples of people taking the Corona sample projects and putting them up without even changing them. While Corona's stuff is MIT licensed, mine is not.

What are your error messages?

topnotch374
User offline. Last seen 1 year 30 weeks ago. Offline
Joined: 1 Feb 2012

Hi Robmiracle,

Thanks for clarifying the part about images in your code... at least now I can somehow understand parts of it.

As probably mentioned earlier, I'm a newbie and just wanted to learn on how this tabs works as I'm planning of creating an app that will have tabs on it. I want to understand fully so I will know how I can create my own. I just need a guide that I can follow and hopefully make my own.

So what I'm currently doing is trying to load your code to run on the simulator so that I will have an idea on how it works.

My plan is to come up with an App that will have 4 to 5 tabs and each screen that corresponds to each tab will also show the tabbar. Basically I want the tabbar to show the whole time.

Any help or direction you can provide will be greatly appreciated as I can't really find a simple information that I can follow... yeah I'm that kind of a Newbie :(

Thanks

robmiracle
User offline. Last seen 26 weeks 5 days ago. Offline
Joined: 18 Jan 2011

Here are some additional resources:

http://blog.anscamobile.com/2011/11/official-tab-bar-widget-now-available/

http://developer.anscamobile.com/reference/index/widgetnewtabbar

Basically you create two graphics for each button. One would be typically gray on black and the other a gradient blue on black, if you're trying to match the iPhone style. Assuming you want to support Retina phones, you would need both a 32x32 and a 64x64 version if each image. If you're following the standard 320x480 letterbox model with @2x appended to your graphic names, then you would have button01.png and button01@2x.png. My example has them in a folder called images. You don't have to put them in an images folder, but it does help with organization.

Next you setup a lua table (Line #58 in my sample above) with an entry for each button. I think it allows you to setup quite a few, but typical Apple iOS apps will have a max of 5. You have to have at least 2 (or you won't need the tab bar controller in the first place).

Each table entry is made up of another table with these values:

label = "Podcasts",
up = "images/tab2.png",
down = "images/tab2_over.png",
width = 32,
height = 32,
onPress = showScreen1,
selected = true

label is the string that appears on the button typically under the icon.

up is the graphic to show when it's not selected.
down is the graphic to show when it IS selected (i.e. the blue one)

In my case these are transparent PNG files and I let the tabbar controller deal with the background.

Width and height should be self explanatory, its the size of the icons regular size, not the @2x version.

onPress is a function to call when the user taps that button. This function is what you will use to change scenes.

An optional "selected" flag. This should by default be applied to your first tab when your app opens, and leave it off the other buttons.

Then on line 94 I call the tabBar controller itself and one of its parameters is the table of buttons.

Since we are commenting about the native tabbar widget and not the community code widget any longer, why don't you make a forum post and let's take the conversation there?

topnotch374
User offline. Last seen 1 year 30 weeks ago. Offline
Joined: 1 Feb 2012

Hi Robmiracle,

Thank you so much for all your explanation... things are getting clearer to me now.

I will try this again... hopefully it will work this time.

I did also made a forum post: http://developer.anscamobile.com/forum/2012/04/06/tab-bar-widgets-beginners

Thanks again for all the help so far. :)

addamiap
User offline. Last seen 1 year 48 weeks ago. Offline
Joined: 26 Mar 2012

Hello Everybody

I'm a beginner with Corona
I'm using your code in order to use tab bar with screens and it works very fine
Now I want to customize it: I have renamed the tabs as follow: Home, Contact, About.
More, when I'm on screen 3 (About) I want to change the tabs: Home, More
How I can change the numbers of tabs and their name?
Thanks in advanced

stephenTU
User offline. Last seen 1 year 8 weeks ago. Offline
Joined: 4 Sep 2011

Was there any answer to this? I am trying to put a tableViewXL into a scene.view which uses functions. Also a text scroll with a image but its taking me time to rework the code. I think I need to call on more locals possibly

robmiracle
User offline. Last seen 26 weeks 5 days ago. Offline
Joined: 18 Jan 2011

@addamlap, I'm not sure how to change the buttons other than creating a 2nd tabBar and putting it on top of the first one.