Nativescript: Slide new page up and over current page

Created on 6 Sep 2016  ยท  7Comments  ยท  Source: NativeScript/NativeScript

I've searched the docs and the issues for a solution but can't seem to find anything useful.

I'm looking for a way to present a page in a similar fashion to how iOS presents the message composer page in the Messages app or Android presents a subpage in the Settings app.

The new page should slide in from the bottom of the page over the top of the current page.

The new page should have a fully functional ActionBar as the pages mentioned above do on both iOS and Android.

The closest thing I have found is to navigate to the new page using:

frames.topmost().navigate({
        ...
        animated: true,
        transition: { name: "slideTop" }
 });

but this pushes the current page up and out of view as the new page transitions in which just looks wrong.

I've also though about using a modal, which gives the desired animation on iOS, but this is presented without an ActionBar and as far as I can see, modals can't be transitioned like this on Android (maybe I'm missing something).

Is there a built in way of performing this kind of page transition? If not then I guess this is a feature request as this is a very common pattern on both OS's.

Thanks

EDIT

I think the iOS transition I'm talking about is the UIModalTransitionStyleCoverVertical as described here: https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/PresentingaViewController.html#//apple_ref/doc/uid/TP40007457-CH14-SW3

I don't know what the equivalent is on Android.

question

Most helpful comment

Hi @3rror404,
This is something related with iOS platform. With xCode 8 some of the methods now are properties. To fix the error, you should replace the following line page.ios.view.backgroundColor = UIColor.clearColor(); with page.ios.view.backgroundColor = UIColor.clearColor; in the above given example.

All 7 comments

Hi @3rror404,
I reviewed your scenario and found that you could use ModalPage as you have suggested in your question. This ModalPage module provides the transition from bottom to top onShowModally page. In regard to that iOS ModalPage will always be fullscreen. As a solution of this behavior you could set Modal page backgroundColor to be transparent. To do that you should use native code as it is shown in the attached example. You could also review this issue, where have been discussed similer problem. To be able to use some native methos you sould install tns-platform-declarations in case you use the NativeScript TypeScript template.

main-page.xml

<Page xmlns="http://schemas.nativescript.org/tns.xsd" backgroundColor="Red" loaded="onLoaded">
  <StackLayout backgroundColor="PaleGreen">
    <Button text="show modal" tap="onTap" />
  </StackLayout>
</Page>

main-page.ts

import {EventData} from "data/observable";
import {Page} from "ui/page";
import {Label} from "ui/label";
import frame = require("ui/frame");

var selected:number = -1;

export function onLoaded(args: EventData) {
    console.log(">>> main-page.onLoaded");
    //console.trace();
}


export function onTap(args: EventData) {
    let page = (<any>args.object).page;

        showModal(page, selected, false);

}


function showModal(page: Page, _selected: number, fullscreen: boolean) {
    page.showModal("./modalView", _selected, function (selectedItem:number) {
        console.log("selected "+selectedItem);
        selected = selectedItem;
    }, fullscreen);
}

modalView.xml

<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="onPageLoaded" class="ModalPageStyle" showingModally="onShowingModally" shownModally="onShownModally" style="height:300px; margin:30px;">

    <GridLayout rows="auto auto auto auto auto auto" col="*">
        <GridLayout  row="0" rows="50" columns="auto * auto">
            <Button fontSize="10" col="0" text="Back" tap="goBack" />
            <Label col="1"  textAlign="center" text="Modal Page" textWrap="true" />
            <Button fontSize="10" col="2" text="Next" tap="" />

        </GridLayout>
       <Label row="1" text="Label 1" textWrap="true" />
       <Label row="2" text="Label 2" textWrap="true" />
       <Label row="3" text="Label 3" textWrap="true" />
       <Label row="4" text="Label 4" textWrap="true" />
       <Label row="5" text="Label 5" textWrap="true" />
    </GridLayout>

</Page>

modalView.ts

import {ObservableArray} from "data/observable-array";
import {Page, ShownModallyData} from 'ui/page';
import {Observable, EventData} from "data/observable";
import frame = require("ui/frame");
import {ListView, ItemEventData} from 'ui/list-view';
import {isIOS} from "platform"

var closeCallback: Function;
export function onPageLoaded(args) {
    var page:Page = <Page>args.object;  






}


export function onShowingModally(args: EventData) {
    console.log(">>> login-page.onShowingModally");
        var page:Page = <Page>args.object;
        if(isIOS){
            page.ios.providesPresentationContextTransitionStyle = true;
            page.ios.definesPresentationContext = true;
            page.ios.modalPresentationStyle = UIModalPresentationStyle.UIModalPresentationOverFullScreen;
            page.ios.view.backgroundColor = UIColor.clearColor();
        } 

}

export function onShownModally(args: ShownModallyData) {
    console.log(">>> login-page.onShownModally, context: " );

    closeCallback = args.closeCallback;

    var modalPage = <Page>args.object;

    if (frame.topmost().currentPage.modal !== args.object) {
        throw new Error(`Error`);
    }

}

export function  goBack(){
    closeCallback();
}

In regard to your second question you could create Custom view that looks like ActionBar and provides the same functionality. I am attaching pure example with Custom Component, where I used GridLayout.

 <GridLayout  row="0" rows="50" columns="auto * auto">
            <Button fontSize="10" col="0" text="Back" tap="goBack" />
            <Label col="1"  textAlign="center" text="Modal Page" textWrap="true" />
            <Button fontSize="10" col="2" text="Next" tap="" />

        </GridLayout>

I hope this is applicable for you.

Hi @tsonevn,

I'm trying to implement the native code that you provided above. however I am receiving the following crash:

JS ERROR TypeError: UIColor.clearColor is not a function. (In 'UIColor.clearColor()', 'UIColor.clearColor' is an instance of UIColor)

JS:

var Platform = require('platform');

function onShowingModally(args) {
    var page = args.object;
    if (Platform.isIOS) {
        page.ios.providesPresentationContextTransitionStyle = true;
        page.ios.definesPresentationContext = true;
        page.ios.modalPresentationStyle = UIModalPresentationStyle.UIModalPresentationOverFullScreen;
        page.ios.view.backgroundColor = UIColor.clearColor();
    }
}
exports.onShowingModally = onShowingModally;

This is in the simulator running iOS10.

Am I doing something incorrectly?

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Component        โ”‚ Current version       โ”‚ Latest version โ”‚ Information โ”‚
โ”‚ nativescript     โ”‚ 2.3.0                 โ”‚ 2.3.0          โ”‚ Up to date  โ”‚
โ”‚ tns-core-modules โ”‚ 2.4.0-2016-09-21-4189 โ”‚ 2.3.0          โ”‚ Up to date  โ”‚
โ”‚ tns-android      โ”‚ 2.3.0                 โ”‚ 2.3.0          โ”‚ Up to date  โ”‚
โ”‚ tns-ios          โ”‚ 2.3.0                 โ”‚ 2.3.0          โ”‚ Up to date  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Hi @3rror404,
This is something related with iOS platform. With xCode 8 some of the methods now are properties. To fix the error, you should replace the following line page.ios.view.backgroundColor = UIColor.clearColor(); with page.ios.view.backgroundColor = UIColor.clearColor; in the above given example.

@tsonevn. Perfect. Thank you.

@tsonevn how implement subject (slide new page up and over current page) in Android?
Parameter animated of showModal method don't produce any effect. NS4

Hi @webleaf.
I reviewed the case with the modal page animation and was able to recreate the problem. I logged new issue here. You can keep track on it for further info.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings