Merge pull request #1529 from NativeScript/trans

Re-factored page navigation transitions. Resolves Issue #811.
This commit is contained in:
Rossen Hristov
2016-02-10 15:20:25 +02:00
10 changed files with 97 additions and 57 deletions

View File

@ -171,12 +171,12 @@ export class NavPage extends Page implements definition.ControlsPage {
var customTransitionModule = require("./custom-transition");
var customTransition = new customTransitionModule.CustomTransition(duration, curve);
navigationTransition = {
transition: customTransition
instance: customTransition
};
}
else {
navigationTransition = {
transition: transitionName,
name: transitionName,
duration: duration,
curve: curve
};
@ -188,7 +188,7 @@ export class NavPage extends Page implements definition.ControlsPage {
backstackVisible: addToBackStackSwitch.checked,
clearHistory: clearHistorySwitch.checked,
animated: animatedSwitch.checked,
navigationTransition: navigationTransition,
transition: navigationTransition,
});
});
stackLayout.addChild(forwardButton);

View File

@ -25,7 +25,7 @@ function _testTransition(navigationTransition: NavigationTransition) {
return page;
},
animated: true,
navigationTransition: navigationTransition
transition: navigationTransition
}
helper.navigateWithEntry(navigationEntry);
@ -65,7 +65,7 @@ export var test_Transitions = function () {
for (d = 0; d < dlen; d++) {
for (c = 0; c < clen; c++) {
_testTransition({
transition: transitions[t],
name: transitions[t],
duration: durations[d],
curve: curves[c]
});
@ -76,7 +76,7 @@ export var test_Transitions = function () {
// Custom transition
var customTransitionModule = require("./custom-transition");
var customTransition = new customTransitionModule.CustomTransition();
_testTransition({transition: customTransition});
_testTransition({ instance: customTransition });
helper.goBack();
}

View File

@ -191,14 +191,14 @@ function _test_PageNavigation_EventSequence(withTransition: boolean) {
if (withTransition) {
var navigationTransition: FrameModule.NavigationTransition = {
transition: "slide",
name: "slide",
duration: 1000,
};
var navigationEntry: FrameModule.NavigationEntry = {
create: pageFactory,
context: context,
animated: true,
navigationTransition: navigationTransition
transition: navigationTransition
}
helper.navigateWithEntry(navigationEntry);
}

View File

@ -53,7 +53,6 @@
"apps/connectivity-demo/app.ts",
"apps/connectivity-demo/main-page.ts",
"apps/custom-root-view/app.ts",
"apps/custom-root-view/list-view.ts",
"apps/cuteness.io/app.ts",
"apps/cuteness.io/details-page.ts",
"apps/cuteness.io/main-page.ts",
@ -91,16 +90,10 @@
"apps/perf-tests/ApplicationLoadTimeAndFPS/mainPage.ts",
"apps/perf-tests/ApplicationSize/app.ts",
"apps/perf-tests/ApplicationSize/mainPage.ts",
"apps/perf-tests/common.d.ts",
"apps/perf-tests/common.ts",
"apps/perf-tests/ComplexObjectGraphMemoryTest/app.ts",
"apps/perf-tests/ComplexObjectGraphMemoryTest/mainPage.ts",
"apps/perf-tests/ControlCreationSpeedTest/app.ts",
"apps/perf-tests/ControlCreationSpeedTest/mainPage.ts",
"apps/perf-tests/controls-page.d.ts",
"apps/perf-tests/controls-page.ts",
"apps/perf-tests/custom-transition.android.ts",
"apps/perf-tests/custom-transition.ios.ts",
"apps/perf-tests/LargeObjectArrayMemoryLeakTest/app.ts",
"apps/perf-tests/LargeObjectArrayMemoryLeakTest/mainPage.ts",
"apps/perf-tests/LargeObjectArrayMemoryLeakTest/native-calls-wrapper.android.ts",
@ -108,8 +101,6 @@
"apps/perf-tests/LargeObjectArrayMemoryLeakTest/native-calls-wrapper.ios.ts",
"apps/perf-tests/LargeObjectArrayMemoryTest/app.ts",
"apps/perf-tests/LargeObjectArrayMemoryTest/mainPage.ts",
"apps/perf-tests/nav-page.d.ts",
"apps/perf-tests/nav-page.ts",
"apps/perf-tests/NavigationMemoryLeakTest/app.ts",
"apps/perf-tests/NavigationMemoryLeakTest/mainPage.ts",
"apps/perf-tests/NavigationTest/app.ts",
@ -127,6 +118,14 @@
"apps/perf-tests/SpeedTests/tests-native.ios.ts",
"apps/perf-tests/SpeedTests/tests.d.ts",
"apps/perf-tests/SpeedTests/tests.ts",
"apps/perf-tests/common.d.ts",
"apps/perf-tests/common.ts",
"apps/perf-tests/controls-page.d.ts",
"apps/perf-tests/controls-page.ts",
"apps/perf-tests/custom-transition.android.ts",
"apps/perf-tests/custom-transition.ios.ts",
"apps/perf-tests/nav-page.d.ts",
"apps/perf-tests/nav-page.ts",
"apps/pickers-demo/app.ts",
"apps/pickers-demo/main-page.ts",
"apps/pickers-demo/model.ts",
@ -149,6 +148,7 @@
"apps/template-settings/view-model.ts",
"apps/template-tab-navigation/app.ts",
"apps/template-tab-navigation/main-page.ts",
"apps/tests/TKUnit.ts",
"apps/tests/app/app.ts",
"apps/tests/app/location-example.ts",
"apps/tests/app/mainPage.ts",
@ -225,13 +225,12 @@
"apps/tests/testRunner.ts",
"apps/tests/text/formatted-string-tests.ts",
"apps/tests/timer-tests.ts",
"apps/tests/TKUnit.ts",
"apps/tests/trace-tests.ts",
"apps/tests/ui-test.ts",
"apps/tests/ui/action-bar/ActionBar_NumberAsText.ts",
"apps/tests/ui/action-bar/action-bar-tests-common.ts",
"apps/tests/ui/action-bar/action-bar-tests.android.ts",
"apps/tests/ui/action-bar/action-bar-tests.ios.ts",
"apps/tests/ui/action-bar/ActionBar_NumberAsText.ts",
"apps/tests/ui/activity-indicator/activity-indicator-tests.ts",
"apps/tests/ui/animation/animation-tests.ts",
"apps/tests/ui/bindable-tests.ts",
@ -707,4 +706,4 @@
"atom": {
"rewriteTsconfig": true
}
}
}

View File

@ -6,6 +6,7 @@ import * as trace from "trace";
import {resolveFileName} from "file-system/file-name-resolver";
import * as fs from "file-system";
import * as builderModule from "ui/builder";
import * as platform from "platform";
var builder: typeof builderModule;
function ensureBuilder() {
@ -138,11 +139,11 @@ export class Frame extends CustomLayoutView implements definition.Frame {
private _backStack: Array<definition.BackstackEntry>;
public _currentEntry: definition.BackstackEntry;
private _animated: boolean;
private _navigationTransition: definition.NavigationTransition;
private _transition: definition.NavigationTransition;
public _isInFrameStack = false;
public static defaultAnimatedNavigation = true;
public static defaultNavigationTransition: definition.NavigationTransition;
public static defaultTransition: definition.NavigationTransition;
// TODO: Currently our navigation will not be synchronized in case users directly call native navigation methods like Activity.startActivity.
@ -325,12 +326,12 @@ export class Frame extends CustomLayoutView implements definition.Frame {
this._animated = value;
}
public get navigationTransition(): definition.NavigationTransition {
return this._navigationTransition;
public get transition(): definition.NavigationTransition {
return this._transition;
}
public set navigationTransition(value: definition.NavigationTransition) {
this._navigationTransition = value;
public set transition(value: definition.NavigationTransition) {
this._transition = value;
}
get backStack(): Array<definition.BackstackEntry> {
@ -399,15 +400,25 @@ export class Frame extends CustomLayoutView implements definition.Frame {
}
public _getNavigationTransition(entry: definition.NavigationEntry): definition.NavigationTransition {
if (entry && isDefined(entry.navigationTransition)) {
return entry.navigationTransition;
if (entry) {
if (platform.device.os === platform.platformNames.ios && isDefined(entry.transitioniOS)) {
return entry.transitioniOS;
}
if (platform.device.os === platform.platformNames.android && isDefined(entry.transitionAndroid)) {
return entry.transitioniOS;
}
if (entry && isDefined(entry.transition)) {
return entry.transition;
}
}
if (isDefined(this.navigationTransition)) {
return this.navigationTransition;
if (isDefined(this.transition)) {
return this.transition;
}
return Frame.defaultNavigationTransition;
return Frame.defaultTransition;
}
public get navigationBarHeight(): number {

View File

@ -202,11 +202,11 @@ export class Frame extends frameCommon.Frame {
frameCommon.Frame.defaultAnimatedNavigation = value;
}
public static get defaultNavigationTransition(): definition.NavigationTransition {
return frameCommon.Frame.defaultNavigationTransition;
public static get defaultTransition(): definition.NavigationTransition {
return frameCommon.Frame.defaultTransition;
}
public static set defaultNavigationTransition(value: definition.NavigationTransition) {
frameCommon.Frame.defaultNavigationTransition = value;
public static set defaultTransition(value: definition.NavigationTransition) {
frameCommon.Frame.defaultTransition = value;
}
get containerViewId(): number {

41
ui/frame/frame.d.ts vendored
View File

@ -5,6 +5,7 @@ declare module "ui/frame" {
import view = require("ui/core/view");
import observable = require("data/observable");
import pages = require("ui/page");
import transition = require("ui/transition");
/**
* Represents the logical View unit that is responsible for navigation withing an application.
@ -77,7 +78,7 @@ declare module "ui/frame" {
/**
* Gets or sets the default navigation transition for this frame.
*/
navigationTransition: NavigationTransition;
transition: NavigationTransition;
/**
* Gets or sets if navigation transitions should be animated globally.
@ -87,7 +88,7 @@ declare module "ui/frame" {
/**
* Gets or sets the default NavigationTransition for all frames across the app.
*/
static defaultNavigationTransition: NavigationTransition;
static defaultTransition: NavigationTransition;
/**
* Gets the AndroidFrame object that represents the Android-specific APIs for this Frame. Valid when running on Android OS.
@ -161,9 +162,19 @@ declare module "ui/frame" {
animated?: boolean;
/**
* Specifies an optional navigation transition. If not specified, the default platform transition will be used.
* Specifies an optional navigation transition for all platforms. If not specified, the default platform transition will be used.
*/
navigationTransition?: NavigationTransition;
transition?: NavigationTransition;
/**
* Specifies an optional navigation transition for iOS. If not specified, the default platform transition will be used.
*/
transitioniOS?: NavigationTransition;
/**
* Specifies an optional navigation transition for iOS. If not specified, the default platform transition will be used.
*/
transitionAndroid?: NavigationTransition;
/**
* True to record the navigation in the backstack, false otherwise.
@ -182,10 +193,28 @@ declare module "ui/frame" {
*/
export interface NavigationTransition {
/**
* Either a string specifying one of the built-in transitions or an user-defined instance of the "ui/transition".Transition class.
* Can be one of the built-in transitions:
* - curl (same as curlUp) (iOS only)
* - curlUp (iOS only)
* - curlDown (iOS only)
* - explode (Android Lollipop an up only)
* - fade
* - flip (same as flipRight)
* - flipRight
* - flipLeft
* - slide (same as slideLeft)
* - slideLeft
* - slideRight
* - slideTop
* - slideBottom
*/
transition: any;
name?: string;
/**
* An user-defined instance of the "ui/transition".Transition class.
*/
instance?: transition.Transition;
/**
* The length of the transition in milliseconds. If you do not specify this, the default platform transition duration will be used.
*/

View File

@ -189,11 +189,11 @@ export class Frame extends frameCommon.Frame {
frameCommon.Frame.defaultAnimatedNavigation = value;
}
public static get defaultNavigationTransition(): definition.NavigationTransition {
return frameCommon.Frame.defaultNavigationTransition;
public static get defaultTransition(): definition.NavigationTransition {
return frameCommon.Frame.defaultTransition;
}
public static set defaultNavigationTransition(value: definition.NavigationTransition) {
frameCommon.Frame.defaultNavigationTransition = value;
public static set defaultTransition(value: definition.NavigationTransition) {
frameCommon.Frame.defaultTransition = value;
}
public requestLayout(): void {
@ -640,8 +640,8 @@ function _getTransitionId(nativeTransition: UIViewAnimationTransition, transitio
}
function _getNativeTransition(navigationTransition: definition.NavigationTransition, push: boolean): UIViewAnimationTransition {
if (types.isString(navigationTransition.transition)) {
switch (navigationTransition.transition.toLowerCase()) {
if (navigationTransition.name) {
switch (navigationTransition.name.toLowerCase()) {
case "flip":
case "flipright":
return push ? UIViewAnimationTransition.UIViewAnimationTransitionFlipFromRight : UIViewAnimationTransition.UIViewAnimationTransitionFlipFromLeft;

View File

@ -47,8 +47,8 @@ export function _clearForwardTransitions(fragment: any): void {
export function _setAndroidFragmentTransitions(navigationTransition: frameModule.NavigationTransition, currentFragment: any, newFragment: any, fragmentTransaction: any): void {
var name;
if (types.isString(navigationTransition.transition)) {
name = navigationTransition.transition.toLowerCase();
if (navigationTransition.name) {
name = navigationTransition.name.toLowerCase();
}
var useLollipopTransition = name && (name.indexOf("slide") === 0 || name === "fade" || name === "explode") && _sdkVersion >= 21;
@ -153,7 +153,7 @@ export function _setAndroidFragmentTransitions(navigationTransition: frameModule
return;
}
var transition: Transition;
var transition: definition.Transition;
if (name) {
if (name.indexOf("slide") === 0) {
var slideTransitionModule = require("./slide-transition");
@ -171,7 +171,7 @@ export function _setAndroidFragmentTransitions(navigationTransition: frameModule
}
}
else {
transition = navigationTransition.transition; // User-defined instance of Transition
transition = navigationTransition.instance; // User-defined instance of Transition
}
if (transition) {

View File

@ -6,13 +6,13 @@ import trace = require("trace");
class AnimatedTransitioning extends NSObject implements UIViewControllerAnimatedTransitioning {
public static ObjCProtocols = [UIViewControllerAnimatedTransitioning];
private _transition: Transition;
private _transition: definition.Transition;
private _operation: UINavigationControllerOperation;
private _fromVC: UIViewController;
private _toVC: UIViewController;
private _transitionType: string;
public static init(transition: Transition, operation: UINavigationControllerOperation, fromVC: UIViewController, toVC: UIViewController): AnimatedTransitioning {
public static init(transition: definition.Transition, operation: UINavigationControllerOperation, fromVC: UIViewController, toVC: UIViewController): AnimatedTransitioning {
var impl = <AnimatedTransitioning>AnimatedTransitioning.new();
impl._transition = transition;
impl._operation = operation;
@ -31,6 +31,7 @@ class AnimatedTransitioning extends NSObject implements UIViewControllerAnimated
case UINavigationControllerOperation.UINavigationControllerOperationPop: this._transitionType = "pop"; break;
case UINavigationControllerOperation.UINavigationControllerOperationNone: this._transitionType = "none"; break;
}
trace.write(`START ${this._transition} ${this._transitionType}`, trace.categories.Transition);
this._transition.animateIOSTransition(containerView, this._fromVC.view, this._toVC.view, this._operation, completion);
}
@ -87,10 +88,10 @@ export class Transition implements definition.Transition {
}
export function _createIOSAnimatedTransitioning(navigationTransition: frame.NavigationTransition, operation: UINavigationControllerOperation, fromVC: UIViewController, toVC: UIViewController): UIViewControllerAnimatedTransitioning {
var transition: Transition;
var transition: definition.Transition;
if (types.isString(navigationTransition.transition)) {
var name = navigationTransition.transition.toLowerCase();
if (navigationTransition.name) {
var name = navigationTransition.name.toLowerCase();
if (name.indexOf("slide") === 0) {
var slideTransitionModule = require("./slide-transition");
var direction = name.substr("slide".length) || "left"; //Extract the direction from the string
@ -102,7 +103,7 @@ export function _createIOSAnimatedTransitioning(navigationTransition: frame.Navi
}
}
else {
transition = navigationTransition.transition;
transition = navigationTransition.instance;
}
if (transition) {