HeaderBar

API Reference: UI.HeaderBar

HeaderBar class represents Navigation Bar for iOS and Action Bar for Android. It is a bar shown on top of page under the statusBar object. You can use it for a way to navigate in the application or for certain functions with buttons. You can also show title of page on HeaderBar.

Creating an instance of HeaderBar class is not valid. You can access the header bar of a page via UI.Page.headerBar property.

On iOS, you should work with header bar in the scope of onLoad() and onShow() callbacks, otherwise behavior would be undefined.

TypeScript code blocks include examples of how to implement, override and components within the theme. You can create page with the UI Editor to make your page compatible with theming and then you can implement themable components programmatically. Once the page is created with the UI Editor, it generates a class under scripts/generated/pages. You can then extend that class with the following TypeScript classes.

Changing the visibility of HeaderBar can cause difference on UI

When you hide the headerBar on iOS, page goes under the statusBar but Android it does not. This behaviour causes the difference between Android & iOS user interfaces. Giving paddingTop for IOS devices might help to solve this problem.

Basic HeaderBar

TypeScript
JavaScript
TypeScript
import PageSampleDesign from 'generated/pages/pageSample';
import FlexLayout = require('sf-core/ui/flexlayout');
import Application = require('sf-core/application');
import System = require("sf-core/device/system");
import HeaderBarItem = require('sf-core/ui/headerbaritem');
import Color = require('sf-core/ui/color');
//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
myItem: HeaderBarItem;
constructor() {
super();
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow: () => void) {
const { headerBar } = System.OS === "Android" ? this : this.parentController;
superOnShow();
Application.statusBar.visible = false;
headerBar.visible = true;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad: () => void) {
superOnLoad();
const { headerBar } = System.OS === "Android" ? this : this.parentController;
headerBar.backgroundColor = Color.create("#00A1F1");
headerBar.title = "Header Bar";
// Border visibility is optional
headerBar.borderVisibility = true;
this.myItem = new HeaderBarItem({
title: "Done",
onPress: function () {
console.log("You pressed Done item!");
}
});
this.headerBar.setItems([this.myItem]);
}
JavaScript
const Page = require("sf-core/ui/page");
const extend = require("js-base/core/extend");
const HeaderBarItem = require('sf-core/ui/headerbaritem');
const Color = require('sf-core/ui/color');
const Application = require('sf-core/application');
var Page1 = extend(Page)(
function(_super) {
_super(this, {
onLoad: function() {
this.headerBar.backgroundColor = Color.create("#00A1F1");
this.headerBar.title = "Header Bar";
// Border visibility is optional
this.headerBar.borderVisibility = true;
var myItem = new HeaderBarItem({
title: "Done",
onPress: function() {
console.log("You pressed Done item!");
}
});
this.headerBar.setItems([myItem]);
},
onShow: function(params) {
Application.statusBar.visible = false;
this.headerBar.visible = true;
}
});
}
);
module.exports = Page1;

Setting HeaderBar Items

HeaderBar items must be set in onLoad or onShow functions of Page.

Default Navigation

There is a default left item on the every HeaderBar. This default button is used to go back in the Router or Navigator history. The back action using this does not send any arguments to the previous page (this cannot be changed). This default behavior can be prevented by:

  • setting a custom left item

  • page.headerBar.leftItemEnabled = false With the default behavior, iOS gesture to swipe back works. If one of the actions described above is used, this also prevents the default swipe back gesture. For Android, on each page, the developer has to write custom back button action.

HeaderBar Badge & Custom View

Since sf-core 3.0.0 it is possible to show a badge number or text with the HeaderBarItem. The badge has a circular or elliptical background, displayed on top-right to the HeaderBarItem. Most common use of the badge is to show the number of notifications or items that user needs to pay attention to. The text of the badge is manually managed by the developer. Basic properties of badge:

  • If the text length of the badge is less, it looks like a circle; otherwise, its width will extend to be an ellipse

  • The width of the badge may not extend the HeaderBarItem width, the larger text will be cut

  • The height of the badge is fixed, does not change

  • By default, it has a red background with white text

  • Font and colors of the badge can be changed via JavaScript code, themes cannot be used

TypeScript
JavaScript
TypeScript
import PageSampleDesign from 'generated/pages/pageSample';
import FlexLayout = require('sf-core/ui/flexlayout');
import Application = require('sf-core/application');
import System = require("sf-core/device/system");
import HeaderBarItem = require('sf-core/ui/headerbaritem');
import ActivityIndicator = require('sf-core/ui/activityindicator');
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import Color = require('sf-core/ui/color');
//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
itemContainerFl: FlexLayout;
myActivityIndicator: ActivityIndicator;
indicatorItem: HeaderBarItem;
itemWithBadge: HeaderBarItem;
constructor() {
super();
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow: () => void) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = true;
headerBar.visible = true;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad: () => void) {
superOnLoad();
const { headerBar } = this;
headerBar.title = "Smartface";
headerBar.dispatch({
type: "updateUserStyle",
userStyle: {
backgroundColor: "#FFFFFF",
titleColor: "#000000"
}
});
this.itemContainerFl = new FlexLayout();
this.dispatch(addChild(`itemContainerFl`, this.itemContainerFl, ".sf-flexLayout", {
height: 50,
width: 50,
flexProps: {
justifyContent: "CENTER",
alignItems: "CENTER"
}
}));
this.myActivityIndicator = new ActivityIndicator();
//@ts-ignore
this.myActivityIndicator.ios.activityIndicatorViewStyle = ActivityIndicator.iOS.ActivityIndicatorViewStyle.NORMAL;
//@ts-ignore
this.itemContainerFl.addChild(this.myActivityIndicator, "myActivityIndicator", ".sf-activityIndicator", {
height: 35,
width: 35,
color: "#00A1F1"
});
this.indicatorItem = new HeaderBarItem({
customView: this.itemContainerFl
});
this.itemWithBadge = new HeaderBarItem({
color: Color.BLUE,
android: {
systemIcon: 17301545 // OR 'ic_dialog_email'
},
ios: {
systemItem: HeaderBarItem.iOS.SystemItem.BOOKMARKS
},
onPress: (): void => {
headerBar.setItems([this.indicatorItem]);
}
});
headerBar.setItems([this.itemWithBadge]);
this.itemWithBadge.badge.visible = true;
this.itemWithBadge.badge.text = "7";
}
JavaScript
const Page = require("sf-core/ui/page");
const extend = require("js-base/core/extend");
const HeaderBarItem = require('sf-core/ui/headerbaritem');
const Color = require('sf-core/ui/color');
const Application = require('sf-core/application');
const ActivityIndicator = require('sf-core/ui/activityindicator');
const FlexLayout = require('sf-core/ui/flexlayout');
var Page1 = extend(Page)(
function (_super) {
_super(this, {
onLoad: function () {
const page = this;
page.headerBar.title = "Smartface";
page.headerBar.backgroundColor = Color.WHITE;
page.headerBar.titleColor = Color.BLACK;
let itemContainerFl = new FlexLayout({
height: 50,
width: 50,
justifyContent: FlexLayout.JustifyContent.CENTER,
alignItems: FlexLayout.AlignItems.CENTER
});
let myActivityIndicator = new ActivityIndicator({
height: 35,
width: 35,
color: Color.create("#00A1F1")
});
myActivityIndicator.ios.activityIndicatorViewStyle = ActivityIndicator.iOS.ActivityIndicatorViewStyle.NORMAL;
itemContainerFl.addChild(myActivityIndicator);
let indicatorItem = new HeaderBarItem({
customView: itemContainerFl
});
let itemWithBadge = new HeaderBarItem({
android: {
systemIcon: 17301545 // OR 'ic_dialog_email'
},
ios: {
systemItem: HeaderBarItem.iOS.SystemItem.BOOKMARKS
},
onPress: function () {
page.headerBar.setItems([indicatorItem]);
}
});
page.headerBar.setItems([itemWithBadge]);
itemWithBadge.badge.visible = true;
itemWithBadge.badge.text = "7";
},
onShow: function (params) {
Application.statusBar.visible = false;
this.headerBar.visible = true;
}
});
}
);
module.exports = Page1;

HeaderBar Title Layout

You can wrap your design with a FlexLayout and set that layout to HeaderBar's titleLayout.

Usage Information

Title Layout must be assigned in onLoad method of the Page.

Recommendation

Usage of Title Layout is not something we recommend for you to use.

Capability Of Title Layout

Title Layout can be used when developer wants to set an ImageView at HeaderBar.

Handling orientation with titleLayout

When using titleLayout together with rotatable pages by setting orientation to AUTO, you should consider different Android and iOS behaviors.

When using it on iOS, you should consider that onOrientationChange event is fired before the change occurs, therefore you should do your resize calculations with care, by using other methods such as timeout.

On Android, the calculations are mostly done by context, therefore keep your calculations to iOS specific.

TypeScript
JavaScript
TypeScript
import PageSampleDesign from 'generated/pages/pageSample';
import FlexLayout = require('sf-core/ui/flexlayout');
import Application = require('sf-core/application');
import HeaderBarItem = require('sf-core/ui/headerbaritem');
import addChild from "@smartface/contx/lib/smartface/action/addChild";
import Color = require('sf-core/ui/color');
import Image = require("sf-core/ui/image");
import ImageView = require("sf-core/ui/imageview");
//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
myFlexLayout: FlexLayout;
myImageView: Image;
myItem: HeaderBarItem;
leftItem: HeaderBarItem;
constructor() {
super();
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow: () => void) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = true;
headerBar.visible = true;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad: () => void) {
superOnLoad();
const { headerBar } = this;
this.myItem = new HeaderBarItem({
title: "Done",
color: Color.BLACK,
onPress: function () {
console.log("You pressed Done item!");
}
});
this.headerBar.setItems([this.myItem]);
this.leftItem = new HeaderBarItem();
this.leftItem.title = "Left";
this.leftItem.color = Color.BLACK;
this.headerBar.setLeftItem(this.leftItem);
this.myFlexLayout = new FlexLayout();
this.dispatch(addChild(`myFlexLayout`, this.myFlexLayout, ".sf-flexLayout", {
width: 250,
height: 50,
backgroundColor: "#000000",
flexProps: {
justifyContent: "CENTER"
}
}));
this.myImageView = new ImageView({
image: Image.createFromFile("images://icon.png")
});
this.myFlexLayout.addChild(this.myImageView, "myImageView", ".sf-imageView", {
width: 30,
height: 30,
backgroundColor: "#000000",
imageFillType: "ASPECTFIT"
});
this.headerBar.title = "";
this.headerBar.titleLayout = this.myFlexLayout;
}
JavaScript
const HeaderBarItem = require("sf-core/ui/headerbaritem");
const FlexLayout = require("sf-core/ui/flexlayout");
const Image = require("sf-core/ui/image");
const ImageView = require("sf-core/ui/imageview");
const Page = require("sf-core/ui/page");
const extend = require("js-base/core/extend");
const Color = require('sf-core/ui/color');
const OS = require('sf-core/device/system').OS;
var Page1 = extend(Page)(
function(_super) {
_super(this, {
onLoad: function() {
var myItem = new HeaderBarItem({
title: "Done",
color: Color.BLACK,
onPress: function() {
console.log("You pressed Done item!");
}
});
this.headerBar.setItems([myItem]);
var leftItem = new HeaderBarItem();
leftItem.title = "Left";
leftItem.color = Color.BLACK;
this.headerBar.setLeftItem(leftItem);
var deviceHeaderBar = OS === "Android" ? this.headerBar.height : this.parentController.headerBar.height;
var myFlexLayout = new FlexLayout({
width: 700,
height: deviceHeaderBar,
justifyContent: FlexLayout.JustifyContent.CENTER
});
myFlexLayout.backgroundColor = Color.BLUE
var image = new ImageView({
image: Image.createFromFile("images://icon.png"),
width: 30,
height: 30,
imageFillType: ImageView.FillType.ASPECTFIT,
});
myFlexLayout.addChild(image);
myFlexLayout.applyLayout();
this.headerBar.title = "";
this.headerBar.titleLayout = myFlexLayout;
},
onShow: function(params) {
this.headerBar.visible = true;
}
});
}
);
module.exports = Page1;

Large Title in iOS 11

Pages may use large titles in the HeaderBar if desired.

prefersLargeTitles property of page's belonging navigator must be set in order to use large title feature.

scripts/app.js
scripts/app.js
const Navigator = require("sf-core/ui/navigator");
const Router = require("sf-core/ui/router");
var myNavigator = new Navigator();
myNavigator.ios.prefersLargeTitles = true; // This is necessary
myNavigator.add("page1", "pages/page1");
myNavigator.add("page2", "pages/page2");
myNavigator.go("page1");
Router.add("myNavigator", myNavigator);
Router.go("myNavigator/page1");
scripts/pages/pag1.js
scripts/pages/pag1.js
const Image = require("sf-core/ui/image");
const HeaderBarItem = require("sf-core/ui/headerbaritem");
const Router = require("sf-core/ui/router");
const extend = require('js-base/core/extend');
const Page = require('sf-core/ui/page');
var page1 = extend(Page)(
function(_super, params) {
_super(this, params);
this.onLoad = function() {
var myItem = new HeaderBarItem({
title: "Next",
onPress: function() {
Router.go("myNavigator/page2");
}
});
this.headerBar.setItems([myItem]);
this.headerBar.title = "page1";
this.headerBar.ios.largeTitleDisplayMode = Page.iOS.LargeTitleDisplayMode.ALWAYS;
}.bind(this);
}
);
module.exports = page1;
scripts/pages/page2.js
scripts/pages/page2.js
const extend = require('js-base/core/extend');
const Page = require('sf-core/ui/page');
var page2 = extend(Page)(
function(_super, params) {
_super(this, params);
this.onLoad = function() {
this.headerBar.title = "page2";
this.headerBar.ios.largeTitleDisplayMode = Page.iOS.LargeTitleDisplayMode.NEVER;
}.bind(this);
}
);
module.exports = page2;

Setting Parent Controller Properties On iOS

According to Smartface Router some of headerBar properties are moved parentController. These properties must be set like page.parentController.headerBar.backgroundImage. These are: -backgroundImage -transparent -alpha -titleColor -visible -itemColor -backgroundColor -height -borderVisibility -backIndicatorImage // iOS only -translucent // iOS only