Creating a Tab Bar
A tab bar can help with quick navigation in your app. Especially if your app is divided into different sections. A tab count of 2 to 5 is optimal.
A tab bar in mos. is created through the interaction of several files. First, the start_config must be set to tab and reference the tabView template. Accordingly, the client_template tabView is required. In addition, each tab requires its own layout file, in which the contents of the respective tab are specified. To add layers to the tab bar, an additional layout file and client templates for each tab are required.
You can skip straight to the copyable code of this tutorial or follow the step by step instructions.
The following mos. components are used in this tutorial. If needed, you can refer to the corresponding wiki pages:
Step by step
Following these instructions you will be able to create a tab bar for your app.
Setting up the tab bar
First, the project needs to be set up to use a tab bar.
For this, the start config has to be edited.
{
"name": "default",
"content": {
"type": "tab",
"staticTemplate": "tabView",
"templateIsNode": true
}
}
- Go to the
default.json
file in the/start_config
directory. - Set the
type
totab
, thestaticTemplate
totabView
and remove the line"layout": "startView",
in thecontent
object.
The tabs have to be defined in the client template, which is referenced in the start config under the field statictemplate
.
{
"name": "tabView",
"content": {
"title": "Tab View",
"content": {
"tabs": [
{
"layout": "c_homeTabContent",
"title": "Home",
"staticTemplate": "homeTab",
"templateIsNode": true
},
{
"layout": "c_awayTabContent",
"title": "Away",
"staticTemplate": "awayTab",
"templateIsNode": true
}
]
}
}
}
- Create a new file
tabView.json
in the/client_template
directory. - Add a
name
field and set itsvalue
totabView
. - Add your tabs in the
tabs
array. Each tab should have alayout
field refering to the layout file that is displayed when the tab is active
Each tab requires the corresponding layout file, which is referenced in the tabView
client template.
{
"name": "c_homeTabContent",
"layers": [
{
"type": "color",
"name": "backgroundColor",
"classes": [
"fullSize",
"background"
]
},
{
"type": "text",
"value": "Home",
"scaleType": "alignCenter",
"classes": [
"fullSize",
"text"
]
}
]
}
- Create a new file in the
/layout
directory for each tab you have specified in the tabs array intabView.json
, e.g.c_homeTabContent.json
. - Add a
name
field and set itsvalue
according to the tab/file name, e.g.c_homeTabContent
. - Add the layers and actions you wish. This is the content that is displayed when the tab is active.
The tab bar with layouts for the content of each tab.
The project has been set up to use a tab bar.
Adding a layout to the tab bar
To add layers to the tab bar, an additional layout file is needed.
Each tab requires a client template that specifies the values to be displayed in the tab bar layout.
{
"name": "homeTab"
}
- Create a new file
homeTab.json
in the/client_template
directory. - Add a new
name
field and set the value tohomeTab
.
{
"name": "homeTab",
"content": {
"title": "Home"
}
}
- Add a new
content
object. - Add a new
title
field in thecontent
object and set its value toHome
.
{
"content": {
"title": "Home",
"content": {
"tabText": {
"value": "Home"
},
"tabIcon": {
"value": "fa-home"
}
}
}
}
- Add another
content
object within the first one. - Add a new
tabText
object to the newcontent
object. - Set the
value
in thetabText
object toHome
. - Add a new
tabIcon
object to the samecontent
object. - Set the
value
in thetabIcon
object tofa-home
. This will translate to a Font Awesome icon later on.
- Repeat these steps for all tabs with the corresponding values.
The style file has to be edited so that it references the layout of the tab bar.
{
"name": "default",
"content": {
"content": {
"default": {
"tabbarLocation": "Bottom",
"tabbarHeights": {
"default": "56pt"
},
"tabbarLayout": "t_tabbar",
"navbarDisabled": true,
}
}
}
}
- Go to the file
default.json
in the/style
directory. - Add the following fields to the
content
object and set their values according to your preferences:tabbarLocation
tabbarHeights
- Add a
tabbarLayout
field to thecontent
object and set its value tot_tabbar
. This specifies the layout that is used for the tab bar.
The tabbar with after editing the style file, but the corresponding layout file is missing.
The tab bar layout file contains the layers displayed in the tab bar. The values for these layers are specified in the respective client templates for each tab.
{
"name": "t_tabbar",
"layers": [
{
"type": "color",
"value": "#2B2F2F",
"classes": [
"fullSize"
]
}
]
}
- Create a new file
t_tabbar.json
in the/layout
directory. This will contain the layers for the tab bar. - Add a
name
field and set its value tot_tabbar
. - Add a
layers
array. - Add a
color
layer to thelayers
array. This will set the background color of the tab bar. - Set the
value
of thecolor
layer to#2B2F2F
or another color of your choice. - Give the
color
layer the classfullSize
, as it is restricted by the dimensions of the tab bar.
{
"name": "t_tabbar",
"layers": [
{
"type": "color",
...
},
{
"type": "text",
"dataKey": "tabIcon",
"font": "FontAwesome",
"fontColor": "#F3F3F3",
"scaleType": "alignCenter",
"fontSize": "30pt",
"constraints": [
{
"type": "pos",
"x": 0,
"y": "5pt"
},
{
"type": "pos",
"anchor": "e",
"relativeAnchor": "e",
"x": 0
}
]
}
]
}
- Add a
text
layer to thelayers
array. - Add a
dataKey
field to thetext
layer and set its value totabIcon
. This refers to thetabIcon
object in the client_templates. - Add a
font
field to thetext
layer and set its value toFontAwesome
. - Style the
text
layer by setting the values for the following fields according to your preferences:fontColor
scaleType
fontSize
constraints
{
"name": "t_tabbar",
"layers": [
{
"type": "color",
...
},
{
"type": "text",
"dataKey": "tabIcon",
...
},
{
"type": "text",
"dataKey": "tabText",
"fontColor": "#F3F3F3",
"scaleType": "alignCenter",
"fontSize": "12pt",
"constraints": [
{
"type": "size",
"height": "14pt"
},
{
"type": "pos",
"x": 0,
"y": "-0pt",
"anchor": "sw",
"relativeAnchor": "sw"
},
{
"type": "pos",
"x": 0,
"anchor": "e",
"relativeAnchor": "e"
}
]
}
]
}
- Add another
text
layer to thelayers
array. - Add a
datakey
field to the newtext
layer and set its value totabText
. This refers to thetabText
object in the client_templates. - Style the new
text
layer by setting the values for the following fields according to your preferences:fontColor
scaleType
fontSize
constraints
A layout has been added to the tab bar.
Adding highlighting to the tab bar
Highlighting the active tab adds to a good user experience and improves navigatio in the app.
For this, additional content
objects have to be added to the tab client templates.
{
"name": "homeTab",
"content": {
"title": "Home",
"content": {
"tabText": {
"value": "Home"
},
"tabIcon": {
"value": "fa-home"
},
"tabIconActive": {
"value": "fa-home",
"conditions": [
{
"state": "visible",
"conditions": {
"left": {
"context": "tabView",
"field": "currentTab"
},
"right": {
"value": 0
},
"mode": "equals"
}
}
]
}
}
}
}
- Go to the file
homeTab.json
in the/client_template
directory. - Add a new
tabIconActive
object to the innercontent
object. - Set the
value
in thetabIconActive
object tofa-Home
, the same as in thetabIcon
object. - Add a
conditions
array to thetabIconActive
object. - Add a
state
field to theconditions
array and set itsvalue
tovisible
. - Add a
conditions
object to theconditions
array with the fowllowing values:left
context
:tabView
field
:currentTab
right
:value
:0
mode
:equals
This compares the index of the active tab (left
) to 0 (right
). If the two sides are equal (mode
), the condition returns true
, indicating that the condition is fulfilled. This means, that the state
of the tabIconActive
object is set to visible
if the condition is met.
{
"name": "homeTab",
"content": {
"title": "Home",
"content": {
"tabText": {
"value": "Home"
},
"tabIcon": {
"value": "fa-home"
},
"tabIconActive": {
"value": "fa-home",
...
},
"tabTextActive": {
"value": "Home",
"conditions": [
{
"state": "visible",
"conditions": {
"left": {
"context": "tabView",
"field": "currentTab"
},
"right": {
"value": 0
},
"mode": "equals"
}
}
]
}
}
}
}
- Add a new
tabTextActive
object to the innercontent
object.
The same steps are now carried out for tabTextActive
as previously for tabIconActive
.
- In the
tabTextActive
object, set thevalue
toHome
, the same as in thetabText
object. - Add a
conditions
array to thetabTextActive
object. - Add a
state
field to theconditions
array and set itsvalue
tovisible
. - Add a
conditions
object to theconditions
array with the fowllowing values:left
context
:tabView
field
:currentTab
right
:value
:0
mode
:equals
- Repeat these steps for all tabs with the corresponding values.
Finally, layers for the highlighting have to be added to the tab bar layout.
{
"name": "t_tabbar",
"layers": [
{
"type": "color",
...
},
{
"type": "text",
"dataKey": "tabIcon",
...
},
{
"type": "text",
"dataKey": "tabText",
...
},
{
"type": "text",
"dataKey": "tabIconActive",
"font": "FontAwesome",
"fontColor": "#34A7C9",
"scaleType": "alignCenter",
"fontSize": "30pt",
"states": {
"visible": {
"hidden": false
}
},
"hidden": true,
"constraints": [
{
"type": "pos",
"x": 0,
"y": "5pt"
},
{
"type": "pos",
"anchor": "e",
"relativeAnchor": "e",
"x": 0
}
]
}
]
}
- Go to the file
t_tabbar.json
in the/layout
directory. - Add a new
text
layer to thelayers
array. - Add a
dataKey
field to thetext
layer and set its value totabIconActive
. This refers to thetabIconActive
object in the client_templates. - Add a
fontColor
field to thetext
layer and set its value to#34A7C9
or a color of your choice for highlighting. - Style the rest of
text
layertabIconActive
the same as thetext
layertabIcon
by using the following fields:font
scaleType
fontSize
constraints
- Add a
hidden
field and set its value totrue
. This hides the layer by default. - Add a
states
field and set its value tovisible {hidden: false}
. This shows the layer, if thestate
isvisible
.
{
"name": "t_tabbar",
"layers": [
{
"type": "color",
...
},
{
"type": "text",
"dataKey": "tabIcon",
...
},
{
"type": "text",
"dataKey": "tabText",
...
},
{
"type": "text",
"dataKey": "tabIconActive",
...
},
{
"type": "text",
"dataKey": "tabTextActive",
"fontColor": "#34A7C9",
"scaleType": "alignCenter",
"fontSize": "12pt",
"states": {
"visible": {
"hidden": false
}
},
"hidden": true,
"constraints": [
{
"type": "size",
"height": "14pt"
},
{
"type": "pos",
"x": 0,
"y": "-0pt",
"anchor": "sw",
"relativeAnchor": "sw"
},
{
"type": "pos",
"x": 0,
"anchor": "e",
"relativeAnchor": "e"
}
]
}
]
}
- Add another new
text
layer to thelayers
array. - Add a
dataKey
field to the new text layer and set its value totabTextActive
. This refers to thetabTextActive
object in the client_templates.
The same steps are now carried out for the new text
layer tabTextActive
as previously for tabIconActive
.
- Add a
fontColor
field to thetext
layer and set its value to#34A7C9
or a color of your choice for highlighting. - Style the rest of the
text
layertabTextActive
the same as thetext
layertabText
by using the following fields:scaleType
fontSize
constraints
- Add a
hidden
field and set its value totrue
. This hides the layer by default. - Add a
states
field and set its value tovisible {hidden: false}
. This shows the layer, if thestate
isvisible
.
Highlighting has been added to the tab bar.
Copyable code
{
"name": "default",
"content": {
"type": "tab",
"staticTemplate": "tabView",
"templateIsNode": true
}
}
{
"name": "tabView",
"content": {
"title": "Tab View",
"content": {
"tabs": [
{
"layout": "c_homeTabContent",
"title": "Home",
"staticTemplate": "homeTab",
"templateIsNode": true
},
{
"layout": "c_awayTabContent",
"title": "Away",
"staticTemplate": "awayTab",
"templateIsNode": true
}
]
}
}
}
{
"name": "c_homeTabContent",
"layers": [
{
"type": "color",
"name": "backgroundColor",
"classes": [
"fullSize",
"background"
]
},
{
"type": "text",
"value": "Home",
"scaleType": "alignCenter",
"classes": [
"fullSize",
"text"
]
}
]
}
{
"name": "c_awayTabContent",
"layers": [
{
"type": "color",
"name": "backgroundColor",
"classes": [
"fullSize",
"background"
]
},
{
"type": "text",
"value": "Away",
"scaleType": "alignCenter",
"classes": [
"fullSize",
"text"
]
}
]
}
{
"name": "homeTab",
"content": {
"title": "Home",
"content": {
"tabText": {
"value": "Home"
},
"tabIcon": {
"value": "fa-home"
},
"tabIconActive": {
"value": "fa-home",
"conditions": [
{
"state": "visible",
"conditions": {
"left": {
"context": "tabView",
"field": "currentTab"
},
"right": {
"value": 0
},
"mode": "equals"
}
}
]
},
"tabTextActive": {
"value": "Home",
"conditions": [
{
"state": "visible",
"conditions": {
"left": {
"context": "tabView",
"field": "currentTab"
},
"right": {
"value": 0
},
"mode": "equals"
}
}
]
}
}
}
}
{
"name": "awayTab",
"content": {
"content": {
"tabText": {
"value": "Away"
},
"tabIcon": {
"value": "fa-plane"
},
"tabIconActive": {
"value": "fa-plane",
"conditions": [
{
"state": "visible",
"conditions": {
"left": {
"context": "tabView",
"field": "currentTab"
},
"right": {
"value": 1
},
"mode": "equals"
}
}
]
},
"tabTextActive": {
"value": "Away",
"conditions": [
{
"state": "visible",
"conditions": {
"left": {
"context": "tabView",
"field": "currentTab"
},
"right": {
"value": 1
},
"mode": "equals"
}
}
]
}
}
}
}
{
"name": "default",
"content": {
"content": {
"default": {
"tabbarLocation": "Bottom",
"tabbarHeights": {
"default": "56pt"
},
"tabbarLayout": "t_tabbar",
"navbarDisabled": true
}
}
}
}
{
"name": "t_tabbar",
"layers": [
{
"type": "color",
"value": "#2B2F2F",
"classes": [
"fullSize"
]
},
{
"type": "text",
"dataKey": "tabIcon",
"font": "FontAwesome",
"fontColor": "#F3F3F3",
"scaleType": "alignCenter",
"fontSize": "30pt",
"constraints": [
{
"type": "pos",
"x": 0,
"y": "5pt"
},
{
"type": "pos",
"anchor": "e",
"relativeAnchor": "e",
"x": 0
}
]
},
{
"type": "text",
"dataKey": "tabText",
"fontColor": "#F3F3F3",
"scaleType": "alignCenter",
"fontSize": "12pt",
"constraints": [
{
"type": "size",
"height": "14pt"
},
{
"type": "pos",
"x": 0,
"y": "-0pt",
"anchor": "sw",
"relativeAnchor": "sw"
},
{
"type": "pos",
"x": 0,
"anchor": "e",
"relativeAnchor": "e"
}
]
},
{
"type": "text",
"dataKey": "tabIconActive",
"font": "FontAwesome",
"fontColor": "#34A7C9",
"scaleType": "alignCenter",
"fontSize": "30pt",
"states": {
"visible": {
"hidden": false
}
},
"hidden": true,
"constraints": [
{
"type": "pos",
"x": 0,
"y": "5pt"
},
{
"type": "pos",
"anchor": "e",
"relativeAnchor": "e",
"x": 0
}
]
},
{
"type": "text",
"dataKey": "tabTextActive",
"fontColor": "#34A7C9",
"scaleType": "alignCenter",
"fontSize": "12pt",
"states": {
"visible": {
"hidden": false
}
},
"hidden": true,
"constraints": [
{
"type": "size",
"height": "14pt"
},
{
"type": "pos",
"x": 0,
"y": "-0pt",
"anchor": "sw",
"relativeAnchor": "sw"
},
{
"type": "pos",
"x": 0,
"anchor": "e",
"relativeAnchor": "e"
}
]
}
]
}
{
"name": ".background",
"content": {
"value": "#121212"
}
}
{
"name": ".fullSize",
"content": {
"constraints": [
{
"type": "pos",
"x": "0",
"y": "0"
},
{
"type": "pos",
"x": "0",
"y": "0",
"anchor": "se",
"relativeAnchor": "se"
}
]
}
}
{
"name": "text",
"content": {
"fontSize": "15pt",
"contentType": "plain",
"fontColor": "#F3F3F3",
"font": "Raleway-Regular"
}
}