ユーザーインターフェイス / コンポーネント / フレーム

フレーム

"Frame"クラスは、異なるページ間のナビゲーションのために責任がある論理ユニットを表します。 アプリケーションは、ビジネスロジックと要件に応じて、単一または複数のFrameインスタンスを持つことができます。

フレーム作成

フレームにはdefaultPageプロパティが設定されている必要があります(必須)。 defaultPageの値として渡されたページは、フレームの初期化時にロードされます。 このidプロパティを使用して、フレームインスタンスへの参照を取得できます。

<Frame id="root-frame" defaultPage="main-page"/>

複数のフレームインスタンスを使用して、より複雑なアプリケーション構造を作成できます。たとえば、タブ項目ごとに異なるフレームを使用しながらTabViewを作成できます。

<TabView>
	<TabViewItem title="First">
		<Frame id="firstFrame" defaultPage="home/home-page" />
	</TabViewItem>
	<TabViewItem title="Second">
		<Frame id="secondFrame" defaultPage="second/second-page" />
	</TabViewItem>
</TabView>

デモソース


フレームリファレンス

NativeScriptのナビゲーションは、FrameAPIに基づいており、目的のフレームのnavigateメソッドを使用しています。 Frameインスタンスへの参照を取得するには、次のメソッドまたはプロパティを使用する必要があります。


注釈: ビジュアルツリーに既にロードされているFrameについてのみ参照を取得できます。 まだ読み込まれていないフレーム(まだ開かれていないモーダルページ内のFrameなど)は取得できません。

デモソース


基本的なナビゲーション

デフォルトページ

アプリケーションのデフォルト(初期)ページを読み込むには、Frame要素のdefaultPageプロパティを使用します。 以下の例では、アプリケーションは<project-folder>/app/home/first-page.xml内にあるページを読み込みます。

<Frame id="my-frame-id" defaultPage="home/first-page"/>

ページ間を移動するには、目的のFrameインスタンスの"navigate"メソッドを使用できます。

const getFrameById = require("tns-core-modules/ui/frame").getFrameById;
	// Example using `getFrameById(frameId)` to get a `Frame` reference
	// As an alternative, we could use `topmost()` method or `page.frame` property
	const frame = getFrameById("my-frame-id");
	frame.navigate("home/second-page");
import { getFrameById } from "tns-core-modules/ui/frame";
	// Example using `getFrameById(frameId)` to get a `Frame` reference
	// As an alternative, we could use `topmost()` method or `page.frame` property
	const frame = getFrameById("my-frame-id");
	frame.navigate("home/second-page");

navigateメソッドは"NavigationEntry"オブジェクトを受け入れます。

const frame = getFrameById("my-frame-id");

const navigationEntry = {
	moduleName: "home/second-page",
	context: { info: "something you want to pass to your page" },
	animated: false
};
frame.navigate(navigationEntry);
const frame = getFrameById("my-frame-id");

// import { NavigationEntry } from "tns-core-modules/ui/frame";
const navigationEntry: NavigationEntry = {
	moduleName: "home/second-page",
	context: { info: "something you want to pass to your page" },
	animated: false
};
frame.navigate(navigationEntry);

以下にNavigaitonEntryプロパティの完全なリストを示します。これらはすべてオプションです。 moduleNameもオプションですが、代わりにcreateを使用して、動的に作成されたページを渡すことができます。

プロパティ 説明
animated boolean アニメーションを使用して新しいページにナビゲートする場合はtrue、そうでない場合はfalse
backstackVisible boolean ナビゲーションをバックスタックに記録する場合はtrue、そうでない場合はfalse。 パラメーターがfalseに設定されている場合、ページは表示されますが、一度そこからナビゲートすると、元のページに戻ることはできません。
bindingContext any ナビゲートするページのバインディングコンテキストになるオブジェクト。オプション。
clearHistory boolean ナビゲーション履歴をクリアする場合はtrue、そうでない場合はfalse。ログインページから移動するときに非常に便利です。
context any ページのonNavigatedToコールバックに渡されるオブジェクト。通常、これはページ間でデータを渡すために使用されます。オプション。
create function Viewインスタンスの作成に使用される関数。オプション。
moduleName string ロードするViewインスタンスを含むモジュールの名前。オプション。
transition NavigationTransition すべてのプラットフォームのオプションのナビゲーション遷移を指定します。指定されない場合、デフォルトのプラットフォーム遷移が使用されます。
transitionAndroid NavigationTransition Androidのオプションのナビゲーション遷移を指定します。指定されない場合、デフォルトのプラットフォーム遷移が使用されます。
transitioniOS NavigationTransition iOSのオプションのナビゲーション遷移を指定します。指定されない場合、デフォルトのプラットフォーム遷移が使用されます。

履歴なしでナビゲートする

ナビゲーションを履歴に追加せずにページに遷移できます。 NavigationEntryのbackstackVisibleプロパティをfalseに設定します。 プロパティが false に設定されている場合、ページは表示されますが、一度そこから他のページへ遷移すると、元のページに戻ることはできません。

	const frame = getFrameById("my-frame-id");

const navigationEntry = {
	moduleName: "home/second-page",
	backstackVisible: false
};
frame.navigate(navigationEntry);
const frame = getFrameById("my-frame-id");

// import { NavigationEntry } from "tns-core-modules/ui/frame";
const navigationEntry: NavigationEntry = {
	moduleName: "home/second-page",
	backstackVisible: false
};
frame.navigate(navigationEntry);

履歴をクリア

新しいページに移動して、ナビゲーション履歴全体を完全にクリアするか否かを決定できます。 NavigationEntryclearHistoryプロパティをtrueに設定します。 これにより、ユーザーは以前にアクセスしたページに戻ることができなくなります。 これは、複数ページの認証プロセスがあり、ユーザーが正常にログインしてアプリケーションの開始ページにリダイレクトされたら、認証ページをクリアする場合に非常に便利です。

const frame = getFrameById("my-frame-id");

const navigationEntry = {
	moduleName: "home/second-page",
	clearHistory: true
};
frame.navigate(navigationEntry);
const frame = getFrameById("my-frame-id");

// import { NavigationEntry } from "tns-core-modules/ui/frame";
const navigationEntry: NavigationEntry = {
	moduleName: "home/second-page",
	clearHistory: true
};
frame.navigate(navigationEntry);

デフォルトでは、すべてのナビゲーションがアニメーション化され、それぞれのプラットフォームのデフォルトの遷移方法(iOSではUINavigationControllerトランジション、AndroidではFragmentトランジション)が使用されます。 遷移タイプを変更するには、NavigationEntrynavigationTransitionプロパティを、 "NavigationTransition"インターフェイスに準拠するオブジェクトに設定します。 NavigationTransitionインタフェースは、4つのオプションのプロパティがあります。

	const frame = getFrameById("my-frame-id");

const navigationEntry = {
	moduleName: "home/second-page",
	animated: true,
	// Set up a transition property on page navigation.
	transition: {
		name: "slide",
		duration: 380,
		curve: "easeIn"
	}
};
frame.navigate(navigationEntry);
const frame = getFrameById("my-frame-id");

// import { NavigationEntry } from "tns-core-modules/ui/frame";
// import { AnimationCurve } from "tns-core-modules/ui/enums";
const navigationEntry: NavigationEntry = {
	moduleName: "home/second-page",
	animated: true,
	// Set up a transition property on page navigation.
	transition: {
		name: "slide",
		duration: 380,
		curve: AnimationCurve.easeIn
	}
};
frame.navigate(navigationEntry);

すべてのフレーム内遷移のデフォルトの遷移方法を指定するには、フレームの遷移時にトランジションプロパティを設定します。

// const getFrameById = require("tns-core-modules/ui/frame").getFrameById;
// const myFrame = getFrameById("firstFrame");
myFrame.transition = { name: "flip" };
myFrame.navigate("main-page");
// const getFrameById = require("tns-core-modules/ui/frame").getFrameById;
// const frame = getFrameById("firstFrame");
frame.transition = { name: "flip" };
frame.navigate("main-page");

アプリ全体のすべてのナビゲーションにデフォルトの遷移方法を指定するには、Frameクラスの静的プロパティdefaultTransitionを設定します。

// const frameModule = require("tns-core-modules/ui/frame");
frameModule.Frame.defaultTransition = { name: "fade" };
// import * as frameModule from "tns-core-modules/ui/frame";
frameModule.Frame.defaultTransition = { name: "fade" };

プラットフォームごとに異なる遷移方法を指定するには、NavigationEntrytransitioniOSおよびtransitionAndroidプロパティを使用します。

const navigationEntry = {
	moduleName: "main-page",
	animated: true,
	// Set up platform specific transitions.
	transitioniOS: {
		name: "curl",
		duration: 380,
		curve: "easeIn"
	},
	transitionAndroid: {
		name: "explode",
		duration: 300,
		curve: "easeOut"
	}
};
const frame = getFrameById("my-frame");
frame.navigate(navigationEntry);
const navigationEntry: NavigationEntry = {
	moduleName: "main-page",
	animated: true,
	// Set up platform specific transitions.
	transitioniOS: {
		name: "curl",
		duration: 380,
		curve: AnimationCurve.easeInOut
	},
	transitionAndroid: {
		name: "explode",
		duration: 300,
		curve: AnimationCurve.spring
	}
};
const frame = getFrameById("my-frame");
frame.navigate(navigationEntry);

nameプロパティを定義済みの遷移のいずれかに設定する代わりに、NavigationTransitionのインスタンスプロパティをTransitionから継承するクラスのインスタンスに設定できます。 プラットフォーム固有のコードを記述して遷移をアニメーション化することにより、カスタムのユーザー定義の遷移を作成できます。 そのためには、Transitionクラスから継承し、プラットフォームごとに1つのメソッドをオーバーライドする必要があります。 プラットフォーム固有のコードがあるため、コードを2つの別々のファイルに分ける必要があります。 例として、スケールアフィン変換を使用して、表示されているページを拡大しながら表示されていないページを縮小するカスタムトランジションを以下に示します。

注釈: 次の例では、ネイティブAPIを使用しています。 TypeScriptを使用する場合、コンパイラエラーなしでこれらのネイティブAPIを使用するには、"tns-platform-declarations"パッケージにdev依存関係を追加する必要があります。 詳細については、IntellisenseとTypeScriptを介したネイティブAPIへのアクセスセクションを参照してください。

custom-transition.android.js/ts

const transition = require("tns-core-modules/ui/transition");
const floatType = java.lang.Float.class.getField("TYPE").get(null);
const CustomTransition = (function (_super) {
	__extends(CustomTransition, _super);
	function CustomTransition() {
		_super.apply(this, arguments);
	}
	CustomTransition.prototype.createAndroidAnimator = function(transitionType) {
		const scaleValues = java.lang.reflect.Array.newInstance(floatType, 2);
		switch (transitionType) {
			case transition.AndroidTransitionType.enter:
			case transition.AndroidTransitionType.popEnter:
				scaleValues[0] = 0;
				scaleValues[1] = 1;
				break;
			case transition.AndroidTransitionType.exit:
			case transition.AndroidTransitionType.popExit:
				scaleValues[0] = 1;
				scaleValues[1] = 0;
				break;
			default:
				break;
		}
		const objectAnimators = java.lang.reflect.Array.newInstance(android.animation.Animator.class, 2);
		objectAnimators[0] = android.animation.ObjectAnimator.ofFloat(null, "scaleX", scaleValues);
		objectAnimators[1] = android.animation.ObjectAnimator.ofFloat(null, "scaleY", scaleValues);
		const animatorSet = new android.animation.AnimatorSet();
		animatorSet.playTogether(objectAnimators);
		const duration = this.getDuration();
		if (duration !== undefined) {
			animatorSet.setDuration(duration);
		}
		animatorSet.setInterpolator(this.getCurve());

		return animatorSet;
	};

	return CustomTransition;
})(transition.Transition);
exports.CustomTransition = CustomTransition;
import { Transition, AndroidTransitionType } from "tns-core-modules/ui/transition";
export class CustomTransition extends Transition {
	public createAndroidAnimator(transitionType: string): android.animation.Animator {
		const scaleValues = (<any>Array).create("float", 2);
		switch (transitionType) {
			case AndroidTransitionType.enter:
			case AndroidTransitionType.popEnter:
				scaleValues[0] = 0;
				scaleValues[1] = 1;
				break;
			case AndroidTransitionType.exit:
			case AndroidTransitionType.popExit:
				scaleValues[0] = 1;
				scaleValues[1] = 0;
				break;
			default:
				break;
		}
		const objectAnimators = (<any>Array).create(android.animation.Animator, 2);
		objectAnimators[0] = android.animation.ObjectAnimator.ofFloat(null, "scaleX", scaleValues);
		objectAnimators[1] = android.animation.ObjectAnimator.ofFloat(null, "scaleY", scaleValues);

		const animatorSet = new android.animation.AnimatorSet();
		animatorSet.playTogether(objectAnimators);

		const duration = this.getDuration();
		if (duration !== undefined) {
			animatorSet.setDuration(duration);
		}

		animatorSet.setInterpolator(this.getCurve());
		return animatorSet;
	}
}

custom-transition.ios.js/ts

// const transition = require("tns-core-modules/ui/transition");
const CustomTransitionIOS = (function (_super) {
	__extends(CustomTransition, _super);
	function CustomTransition() {
		_super.apply(this, arguments);
	}
	CustomTransition.prototype.animateIOSTransition = function(containerView, fromView, toView, operation, completion) {
		toView.transform = CGAffineTransformMakeScale(0, 0);
		fromView.transform = CGAffineTransformIdentity;
		switch (operation) {
			case UINavigationControllerOperation.UINavigationControllerOperationPush:
				containerView.insertSubviewAboveSubview(toView, fromView);
				break;
			case UINavigationControllerOperation.UINavigationControllerOperationPop:
				containerView.insertSubviewBelowSubview(toView, fromView);
				break;
			default:
				break;
		}
		const duration = this.getDuration();
		const curve = this.getCurve();
		UIView.animateWithDurationAnimationsCompletion(duration, () => {
			UIView.setAnimationCurve(curve);
			toView.transform = CGAffineTransformIdentity;
			fromView.transform = CGAffineTransformMakeScale(0, 0);
		}, completion);
	};

	return CustomTransitionIOS;
})(transition.Transition);
exports.CustomTransitionIOS = CustomTransitionIOS;
// import { Transition } from "tns-core-modules/ui/transition";
declare let UINavigationControllerOperation: any; // or use tns-platform-declarations

export class CustomTransitionIOS extends Transition {
	public animateIOSTransition(containerView: UIView,
	fromView: UIView,
	toView: UIView,
	operation: UINavigationControllerOperation,
	completion: (finished: boolean) => void): void {
		const originalToViewTransform = toView.transform;
		const originalFromViewTransform = fromView.transform;

		// http://stackoverflow.com/questions/216076/uiview-scale-to-0-using-cgaffinetransformmakescale
		const scaleTransform = CGAffineTransformMakeScale(0.0001, 0.0001);

		toView.transform = scaleTransform;
		fromView.transform = CGAffineTransformIdentity;

		switch (operation) {
			case UINavigationControllerOperation.UINavigationControllerOperationPush:
				containerView.insertSubviewAboveSubview(toView, fromView);
				break;
			case UINavigationControllerOperation.UINavigationControllerOperationPop:
				containerView.insertSubviewBelowSubview(toView, fromView);
				break;
			default:
				break;
		}

		const duration = this.getDuration();
		const curve = this.getCurve();
		UIView.animateWithDurationAnimationsCompletion(duration, () => {
			UIView.setAnimationCurve(curve);
			toView.transform = CGAffineTransformIdentity;
			fromView.transform = scaleTransform;
		}, (finished: boolean) => {
				toView.transform = originalToViewTransform;
				fromView.transform = originalFromViewTransform;
				completion(finished);
		});
	}
}

各フレームは、ナビゲーションスタックでユーザーがアクセスしたページを追跡します。 前のページに戻るに"goBack"は、現在のフレームインスタンスのメソッドを使用する必要があります。 バックナビゲーションが可能であることを確認するには、"canGoBackboolean"プロパティを使用します。

// const getFrameById = require("tns-core-modules/ui/frame").getFrameById;
const myFrame = getFrameById("my-frame");
myFrame.goBack();
// import { getFrameById } from "tns-core-modules/ui/frame";
const myFrame = getFrameById("my-frame");
myFrame.goBack();

デモソース


ダイナミックナビゲーション

より動的な画面遷移方法は、ナビゲートしたいページのインスタンスを返す関数を提供することにより実行できます。

const frame = getFrameById("my-frame-id");
frame.navigate({
	create: () => {
		const stack = new StackLayout();
		const label = new Label();
		label.text = "Hello, world!";
		stack.addChild(label);

		const page = new Page();
		page.content = stack;

		return page;
	}
});
const frame = getFrameById("my-frame-id");

	frame.navigate({
	create: () => {
		const stack = new StackLayout();
		const label = new Label();
		label.text = "Hello, world!";
		stack.addChild(label);

		const page = new Page();
		page.content = stack;

		return page;
	}
});

デモソース


ナビゲーション中にコンテキストを渡す

別のページに移動すると、NavigationEntryオブジェクトを使用してページにコンテキストを渡すことができます。 NavigationEntry には、次の2つの異なる(オプションの)プロパティがあります。

両方のプロパティは、ナビゲート中にコンテキストを渡すために使用されますが、bindingContextプロパティはランディングページのバインディングコンテキストを自動的に割り当てます。

ナビゲーション中のコンテキストの取得

bindingContextで送信されたコンテキストは、ナビゲートされた(ランディング)ページのバインディングコンテキストとして自動的に割り当てられます。 contextプロパティを介して送信されたコンテキストの取得は、2つの異なるアプローチで実現できます。

function onNavigatedTo(args) {
	const page = args.object;
	const navigationContext = page.navigationContext;

	// The navigation event arguments are of type NavigatedData and provide another way to grab the passed context
	const context = args.context;

	page.bindingContext = navigationContext;
}
exports.onNavigatedTo = onNavigatedTo;
import { Page, NavigatedData } from "tns-core-modules/ui/page";

// Event handler for Page "navigatedTo" event attached in details-page.xml e.g.
export function onNavigatedTo(args: NavigatedData): void {
	const page: Page = <Page>args.object;
	const navigationContext = page.navigationContext;

	// The navigation event arguments are of type NavigatedData and provide another way to grab the passed context
	const context = args.context;

	page.bindingContext = navigationContext;
}

デモソース


アクションバーの可視性

actionBarVisibilityは、現在のフレームのiOSのナビゲーションバーとAndroidのアクションバーの可視性を制御するプロパティです。 フレームに直接設定する必要があり、autoneveralwaysの3つのオプション値があります。

注釈: 2つのプロパティ(never, always)の一部を設定し、 現在読み込まれているページでActionBarをすぐに非表示/表示する必要がある場合、 PageactionBarHiddenプロパティをtrueまたはfalseに設定する必要があります。
<Frame id="my-frame-id" actionBarVisibility="never" defaultPage="home/home-page"/>

デモソース


関連項目 Page ActionBar

入門

コアコンセプト

ユーザーインターフェース

ツール

ハードウェアアクセス

プラグインの開発

リリース

アプリテンプレート

パフォーマンスの最適化

フレームワークモジュール

ガイド

サポートを受ける

トラブルシューティング

Siedkick