3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ionic4で画面遷移アニメーションの方向をIonic3のように使い分けたい

Posted at

Ionic4では画面遷移の実装が変更された影響か、Ionic3のような画面遷移アニメーションの変更ができなくなってしまった。この問題に対する暫定的な対処方法を説明する。

なお、Ionic 4.1.2 + Angularの構成で、画面遷移に<ion-router-outlet>を主に利用している前提とする。

Ionicにおけるアニメーションの種類

Ionicでは、画面遷移時にアニメーション効果が発生する。このアニメーション効果にはMaterial Design風の効果とiOS風の効果の2種類があり、さらに、前進用と後退用のアニメーションが用意されている。

animation     direction
'forward' 'back'
'md' これはmdモードでのforwardアニメーションです。 これはmdモードでのbackアニメーションです。
'ios' これはiOSモードでのforwardアニメーションです。 これはiOSモードでのbackアニメーションです。

Ionic3の場合は、この4パターンのアニメーションをNavControllerのメソッドから制御することができた。
※オプションを省略した場合は、プラットフォームに対応してanimationが適用される。

animation     direction
'forward' 'back'
'md' navController.push(NextComponet, {}, { animation: 'md', direction: 'forward' }) navController.push(NextComponent, {}, { animation: 'md', direction: 'back' })
'ios' navController.push(NextComponet, {}, { animation: 'ios', direction: 'forward' }) navController.push(NextComponent, {}, { animation: 'ios', direction: 'back' })

Ionic4での問題

しかし、Ionic4のNavControllerではanimationを指定するオプションが削除され、forwardbackの区別しかつけられなくなってしまった

animation     direction
'forward' 'back'
N/A navController.navigateForward('nextPath', {}, { direction: 'forward' }) navController.navigateForward('nextPath', {}, { direction: 'back' })

2019年5月現在、ドキュメントで説明されている限りは、遷移ごとにanimationを切り替える方法は提供されていない。このため、iOSテーマでは常に横方向、MDテーマでは常に上下のアニメーションが強制されることになる。

デザイン上は使い分けたい

この仕様は、アニメーションを使って画面間の関係を表現したいときに単純に不便だ。UIデザイン的には、左右のアニメーションと上下のアニメーションは明確に意味が異なっているし、プラットフォームごとにどちらかへ統一するべき挙動であるとも思えない

参考:アプリに最適なアニメーション遷移とスピードを考えてみよう!

暫定的な解決策

プラットフォーム/テーマに関係なく、Ionic3のように都度画面遷移の方向を変える方法がないか色々と試行錯誤した方法を以下へ記載する。

ただし、ドキュメントに記載がなかったり内部プロパティを使っているものは、今後の仕様変更で削除される可能性があることにも注意したい。

<ion-router-outlet>mode属性を指定する

今のところドキュメントに記載されていないが、<ion-router-outlet mode="ios">のようにmode属性を指定すると、画面遷移のデフォルトの挙動をプラットフォームから独立して変更させることができる。

つまり、アプリ全体を通じて左右アニメーションが多い場合はmode="ios"、上下アニメーションが多い場合はmode="md"を指定すると都合が良くなる。

<ion-router-outlet>mode属性を動的に変化させる

さらに、このmode属性を動的に変化させた場合、そのとき付いている値に応じてアニメーションの種類も変化する。

app.component.ts
@Components({
  selector: 'app-route',
  template: '<ion-app><ion-router-outlet [attr.mode]="mode"></ion-router-outlet></ion-app>'
})
export class AppComponent {
    public mode: string = 'ios';
    constructor(...){...}
}
child.component.ts
@Components({
  selector: 'child-component',
  template: `
    <ion-button (click)="navForward('md')">MD Mode</ion-button>
    <ion-button (click)="navForward('ios')">iOS Mode</ion-button>
  `
})
export class ChildComponent {
    constructor(
     private navCtrl: NavController,
     @Optional() @Host() @SkipSelf() private app: AppComponent,
    ){...}

    public navForward(mode: string): void {
      this.app.mode = mode;
      this.navCtrl.navigateForward('next-page');
    }
}

なぜmode属性が効いているのか

実装を見ると、modeプロパティが画面遷移を実行するときのパラメータの一部になっている。
しかし、@internalコメントもあるため将来的に削除される可能性が否定できない。

<ion-nav>のメソッドオプションを使う

Ionic4ではルーティングの仕様が変わり、推奨では<ion-router-outlet>でのルーティングが推奨されている。
一方で、Ionic3にもあった<ion-nav>での画面遷移も引き続き残されている。
(ただし、Ionic3と同じ仕様ではない。)

これを使うことで、遷移の度にmodeを指定することもできる。

とはいえ、Angular Routerでの実装に慣れているとかなり使いにくい。

完全な解決策は見つからず…

結局、完全・安全な解決策は見つかっていない。もし良い方法が見つかった場合には更新したい。

3
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?