Skip to main content
Version: Next

Page

API Reference: UI.Page

Basic Page

Page class stands for showing different interfaces. Pages can be considered as screens.
Every page has its own lifecycle: load, show and hide. Application should have at least one page otherwise user will just see a black screen.

Page has an embedded flex layout, into which you can add views.

Please refer to the related guides for best practices of page usage and page navigation.

See also UI.Pages to see how to display a page on the screen.

import PageSampleDesign from "generated/pages/pageSample";
import { Route, Router } from "@smartface/router";

//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
constructor(private router?: Router, private route?: Route) {
super({});
}

/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
*/
onShow() {
super.onShow();
}

/**
* @event onLoad
* This event is called once when page is created.
*/
onLoad() {
super.onLoad();
}
}
Consider this information when you create your application flow.

On iOS, onShow() function is called when page is about to show.
On Android, it is called when page is shown on screen.

Origin of Page

On Android device screen coordinates start after statusBar, the most top left; on iOS it starts the most top left.

Passing Data between Pages

Like in the example shown at Reveal Pages section, you can pass any data to another page while navigating to another page. However, There is no OOTB (Out of the Box) way to pass a variable while going back.

Check our Router Module to get more information about passing data between pages.

Best Practice of Passing data while going back or dismissing

When passing data in-between modal pages, you should use a mutual medium. In this example, a module scoped variable was used to get username which was received under login page. Normally, a state management like redux should be used. More info can be found at this guide.

Disabling Touch of Page

When dealing with services or async methods, you might want to disable all touch interaction to the page. There are two ways of doing that:

  • Adding a full-page indicator to let user know that application is processing
  • Adding an indicator to a component (e.g. button)
  • Adding a label or something different to let the user know that you are loading something

For full-page indicator, refer to the Dialog document below:

Dialog

For component indicators, you can have two different approach:

  • Adding a fully transparent Dialog to prevent users from touching anything
  • Disabling the touch interactions programmatically

If you are implementing an upload service or something that can be shut off during the process, transparent dialog will not be a good solution for you.

For other 2 solutions, you need to temporarily disable the touch action of the page. Here is an example scenario:

scripts/pages/pageSample.ts
import PageSampleDesign from "generated/pages/pageSample";
import System from "@smartface/native/device/system";
import { Route, Router } from "@smartface/router";

export default class PageSample extends PageSampleDesign {
isPageTouchEnabled = true;
touchCounter = 0;
constructor(private router?: Router, private route?: Route) {
super({});
}

async yourServiceCall(): Promise<void> {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), 3000);
});
}

initButtons() {
this.btnTimeout.onPress = async () => {
this.togglePageTouch(false);
await this.yourServiceCall();
this.togglePageTouch(true);
};
this.btnCounter.onPress = () => {
this.touchCounter++;
this.btnCounter.text = `Touch Counter : ${this.touchCounter}`;
};
}

togglePageTouch(touchEnabled: boolean) {
this.isPageTouchEnabled = touchEnabled;
this.btnTimeout.enabled = this.isPageTouchEnabled;
this.lblTouchIndicator.text = `Current Touch Status : ${
this.isPageTouchEnabled ? "Enabled" : "Disabled"
}`;
if (System.OS === System.OSType.IOS) {
this.layout.touchEnabled = this.isPageTouchEnabled;
} else {
/**
* If you need to use this event somewhere else, add the code snippet below.
*/
this.layout.android.onInterceptTouchEvent = () => {
if (this.isPageTouchEnabled === false) {
return !this.isPageTouchEnabled;
}
// ...your other code
};
}
}

onShow() {
super.onShow();
}

onLoad() {
super.onLoad();
this.initButtons();
}
}
info

If you have a SwipeView, TabbarController or BottomTabbar, those are outside of the page scope so their touches cannot be prevented by this method. You have to use a dialog to prevent their touches.

Padding for Pages

When adding padding to the layout of the entire page, specific padding values need to be entered for all edges.

When individual padding is given to all edges of UI elements on the page to avoid breaking their own paddings and allowing them to adjust automatically, you will be able to use this globally throughout the page.

note

Please note that if you assign and use this value through the 'this.layout.padding' property, it won't have any effect on the page.

scripts/pages/pageSample.ts
export default class PageSample extends PageSampleDesign {
private disposeables: (() => void)[] = [];
lbl: StyleableLabel;
constructor(private router?: Router, private route?: Route) {
super({});
this.lbl = new StyleableLabel();
console.log('[page1] constructor');
}

/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
*/
onShow() {
super.onShow();
console.log('[page1] onShow');

this.layout.paddingLeft = 100
this.layout.paddingRight = 100
this.layout.paddingTop = 100
this.layout.paddingBottom = 100
}
/**
* @event onLoad
* This event is called once when page is created.
*/
onLoad() {
super.onLoad();
}
}

Other Page Types

Aside from normal page which opens left to right (or right to left on RTL interfaces), there are some other page types that you can use.

Pop-up Pages (Modal)

Pop-up page act like full-screen dialog, but also it is a fully fledged page. After using the pop-up page, you can dismiss the pop-up page and will return the page that used before pop-up. To use pop-up page, set modal property of route in your router. You can find an example below.

In this example, styling scheme of this guide is used with a few addition. Also, the theme smartfaceLightTheme was used.

More info can be found on page below:

Using UI Editor and Classes
info
  • Before running the sample code below, make sure you create the following pages on UI Editor:

    • pgWelcome
    • pgLogin
  • While creating the pages, UI Editor was used. Please make sure to add the pages and their UI style properly.

  • In this example, styling scheme of this guide is used with a few addition. Also, the theme smartfaceLightTheme was used.

tip

Do not forget to change your route path defined on start.ts file.

scripts/routes/index.ts
import { NativeRouter, NativeStackRouter, Route } from "@smartface/router";
import Application from "@smartface/native/application";
import PgWelcome from "../pages/pgWelcome";
import PgLogin from "../pages/pgLogin";

Application.on("backButtonPressed", () => {
NativeRouter.getActiveRouter()?.goBack();
});

const router = NativeRouter.of({
path: "/",
to: "/root",
isRoot: true,
routes: [
NativeStackRouter.of({
path: "/root",
to: "/root/welcome",
routes: [
Route.of({
path: "/root/welcome",
build: (router, route) => new PgWelcome(router, route),
}),
NativeStackRouter.of({
path: "/root/user",
to: "/root/user/login",
modal: true, // This is essential
routes: [
Route.of({
path: "/root/user/login",
build: (router, route) => new PgLogin(router, route),
}),
],
}),
],
}),
],
});

export default router;

Reveal Pages

API Reference: TransitionViews

Transitions are the animated changes between two pages, states or views to provide visual continuity to the user interface. It works like PopupPage. Use transitionId to mark related View_s. Each _View must be linked with unique id.

TransitionId Linking

TransitionId of View must be set and link before onShow methods and creating instance of second page.

info

Before running the sample code below, make sure you create the following pages on UI Editor:

  • pgMain
  • pgDetail

While creating the pages, UI Editor was used. Please make sure to add the pages and their UI style properly.

info

Do not forget to change your main route push on start.ts

Using UI Editor and Classes
.ui/pgMain.pgx
{
"components": [
{
"className": ".page",
"id": "0216-a586-68ea-ef16",
"initialized": true,
"props": {
"children": [
"e251-dc93-1cce-a061",
"e5bc-0b15-1b36-b8d6",
"c8dc-c2bc-eac7-33e3"
],
"name": "pgMain",
"orientation": "PORTRAIT",
"parent": null
},
"type": "Page",
"userProps": {}
},
{
"className": ".statusBar",
"id": "e251-dc93-1cce-a061",
"props": {
"children": [],
"isRemovable": false,
"name": "statusBar",
"parent": "0216-a586-68ea-ef16"
},
"type": "StatusBar",
"userProps": {}
},
{
"className": ".headerBar",
"id": "e5bc-0b15-1b36-b8d6",
"props": {
"children": [],
"isRemovable": false,
"name": "headerBar",
"parent": "0216-a586-68ea-ef16",
"title": "Main Page"
},
"type": "HeaderBar",
"userProps": {
"title": "Main Page"
}
},
{
"className": ".gridView",
"id": "c8dc-c2bc-eac7-33e3",
"props": {
"children": ["a41a-fe3a-cfe8-7bb5"],
"name": "gvMain",
"parent": "0216-a586-68ea-ef16",
"usePageVariable": true
},
"type": "GridView",
"userProps": {
"flexProps": {
"flexGrow": 1
},
"layoutManager": {
"spanCount": 2
},
"testId": "pRB1URCFU",
"usePageVariable": true
}
},
{
"className": ".gridViewItem .gridViewItem-simple",
"hiddenComponent": false,
"id": "a41a-fe3a-cfe8-7bb5",
"initialized": true,
"props": {
"children": [],
"name": "simple_gridviewItem",
"parent": "c8dc-c2bc-eac7-33e3"
},
"source": {
"page": "__library__",
"type": "simple_gridviewItem",
"id": "aea8-55c1-833e-4baa"
},
"type": "GridViewItem",
"userProps": {
"flex": {
"positionType": 0
},
"flexProps": {
"positionType": "RELATIVE"
},
"height": 227,
"left": 0,
"testId": "6PcXnnHpZ",
"top": 0
}
}
]
}

The guides which are used:

GridViewUsing ListView with UI Editor

Also, take a look into Router Repository

https://github.com/smartface/router