Skip to main content
Version: 7.0.1

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:

import PgNoTouchDesign from "generated/pages/pgNoTouch";
import System from "@smartface/native/device/system";
import { Route, Router } from "@smartface/router";

export default class PgNoTouch extends PgNoTouchDesign {
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.

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

Before you use the example, make sure to create following pages and theme:

  • pgWelcome as page
  • pgLogin as page
  • smartfaceLightTheme as a theme
import {
NativeRouter,
NativeStackRouter,
Route
} from "@smartface/router";
import System from "@smartface/native/device/system";
import Application from "@smartface/native/application";
import * as Pages from "pages";

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

/**
* On Android, onShow of the dismissed page will not trigger on its own.
* Therefore, we call it ourselves at routeDidEnter event.
*/
const androidModalDismiss = (router, route) => {
const { view, action } = route.getState();
if (System.OS === System.OSType.ANDROID && view && action === "POP") {
view.onShow && view.onShow();
}
};

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 Pages.PgWelcome(router, route),
routeDidEnter: androidModalDismiss
}),
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 Pages.PgLogin(router, route)
})
]
})
]
})
]
});

export default router;
tip

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

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:

  • pgUserList
  • pgUser

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

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

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

The guides which are used:

GridViewUsing ListView with UI Editor

Also, take a look into Router Repository

https://github.com/smartface/router