はじめに

NativeScript(NativeScript-Vue) で次入力欄にフォーカスする方法を整理した。

TL;DR

目次

  1. はじめに
  2. TL;DR
  3. 環境・条件
  4. 詳細
    1. 前置き
      1. returnKeyType=”next” は iOS では動作しない
      2. nativescript-IQKeyboardManager も動作しない
    2. 本題: 次フィールドにフォーカスする方法
  5. まとめ
  6. 参考文献

環境・条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.5
BuildVersion: 19F101

$ node -v
v12.7.0

$ npm -v
6.14.5

$ tns --version
6.5.0

$ grep -C1 version package.json
"tns-android": {
"version": "6.5.1"
},
"tns-ios": {
"version": "6.5.1"
}

$ tns plugin
Dependencies:
┌───────────────────────────────┬─────────────────────┐
│ Plugin │ Version │
│ @nativescript/theme │ ^2.2.1 │
│ @vue/devtools │ ^5.0.6 │
│ nativescript-socketio │ ^3.2.1 │
│ nativescript-toasty │ ^1.3.0 │
│ nativescript-vue │ ^2.4.0 │
│ nativescript-vue-devtools │ ^1.2.0 │
│ tns-core-modules │ ^6.0.0 │
└───────────────────────────────┴─────────────────────┘
Dev Dependencies:
┌────────────────────────────────────┬─────────┐
│ Plugin │ Version │
│ @babel/core │ ^7.0.0 │
│ @babel/preset-env │ ^7.0.0 │
│ babel-loader │ ^8.0.2 │
│ nativescript-dev-webpack │ ^1.0.0 │
│ nativescript-vue-template-compiler │ ^2.0.0 │
│ nativescript-worker-loader │ ~0.9.0 │
│ node-sass │ ^4.9.2 │
│ vue-loader │ ^15.4.0 │
└────────────────────────────────────┴─────────┘

詳細

前置き

最終的なコードだけ見たい人はスキップして本題へ。

returnKeyType=”next” は iOS では動作しない

TextField には returnKeyType というプロパティがあり、done, next, go, search, send が指定できる。

試しに returnKeyType="next" を指定してみたところ Android では期待通りに動作したが、iOS ではリターンキーが「次へ」という表記にはなるもののキーボードが閉じるという動作になった。

NativeScript の Issue #5086, #2809 にて議論されている通り既知の問題の模様。

上記 Issue Comment 内に nativescript-IQKeyboardManager を使うと良い的な記述があったので試した。

nativescript-IQKeyboardManager も動作しない

tjvantoll/nativescript-IQKeyboardManager は、iOS でよく見る「<, > タップで前後フィールド移動するやつ」を表示するプラグイン。

なんだけど Nativescript 6.x support · Issue #68 を見る限り NativeScript 6.x 系は未サポートらしく、実際に入れてみても期待動作にならなかった。

本題: 次フィールドにフォーカスする方法

参考:

上記ページを参考に、以下のようにすることで解決した。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<template>
<Page ref="page">
<StackLayout>
<TextField
id="field1"
@returnPress="focusTo('field2')"
/>
<TextField
id="field2"
@returnPress="focusTo('field2')"
/>
<TextField
id="field3"
/>
</StackLayout>
</Page>
</template>

<script >
export default {
methods: {
focusTo(id) {
const page = this.$refs.page.nativeView;
page.getViewById(id).focus();
},
},
}
</script>

(見ればわかるけど) ざっくり解説。

  • <Page ref="page"> とすると this.$refs.page.nativeViewPage オブジェクトにアクセスできるようになる
  • returnPress イベントにハンドラを設定
    • Vue なので @returnPress
  • getViewById で次の TextField を指定
    • フィールド識別用に TextFieldid を付与しておく
  • TextField.forcus() でフォーカス

まとめ

参考文献

関連記事