InputFieldの罠
Unity標準UIのInputFieldには微妙なバグ(仕様?)があります。
たとえば、こんな感じで
全画面InputFieldしか無い画面をScrollViewのContentに配置すると
スクロールさせようとタップした途端にInputFieldにフォーカスがあたってしまい、スクロールがキャンセルされてしまうのです。
なのでこの画像の例だと、InputField(16)を選択するのがすごく大変になります(ScrollBarでスクロールさせるか、Editor/PCならマウスホイールでできなくもないですが・・・いけてない)
なお、同じく標準UIのButtonなんかはスクロールも出来るし、タップも出来るんですよ。おかしくないですか。
あーあ。次のバージョンで修正されるといいなー。
と。そうも言ってられないので今できる事をしましょう。
前述の通りInputFieldはスクロール対応じゃないですが、Buttonはスクロール対応なので、InputFieldの上に同じサイズの透明なButtonをかぶせてしまう荒業を試してみます。
上記のように一つ親(ScrollableInputField)を作って、その中にInputFieldとButtonを。
なおButtonはボタン判定はあるけど、見えない(InputFieldを隠さない)ようにしなくてはなので
α値を0にしたり、TransitionをNoneにしたりしておきます。
(※このScrollableInputFieldをPrefab化して使う。)
スクロールは出来るようになった。 がしかし・・・。
しかしこれだとInputFieldに入力できないんですよね。
まぁ、そりゃそうです。上にかぶさっているボタンがタップイベントを奪うので、InputFieldにフォーカスが行かなくなってしまっています。
なので一工夫。この透明ボタンのonClickにInputFieldのactivate処理を入れてあげれば上手く行きそうです。
以下ソース
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class ScrollableInputField : MonoBehaviour
{
[SerializeField]
private InputField _targetInputField;
[SerializeField]
private Button _guardButton;
public UnityEvent OnFocus = new UnityEvent();
void Start ()
{
_guardButton.onClick.AddListener(() =>
{
_targetInputField.ActivateInputField();
OnFocus.Invoke();
});
}
}
めちゃめちゃ短いですね。
そして忘れずにInspectorでInputFieldとButtonをセットしておきます。
これで、ドラッグでスクロールできるし、タップすれば入力が出来るInputFieldの完成です!
良いScrollライフを。
おまけ
ところで謎のUnityEvent OnFocus
があります。
これは折角ボタンのOnClickでフォーカスを発生させているので、副次的な効果としてフォーカスの取得もUnityEvent化してしましまいました。
(余計なお世話な人は消しちゃってください。)
まぁ、見ての通り非常にシンプルで、ボタンクリックイベントでフォーカスするついでに
OnFocused.Invoke(this);
とするだけで外部から擬似的にフォーカスイベントが取れる形になるのでお得感あります。1
例えばフォーカスが当たると同時にそのInputFieldを画面の真ん中に持ってくる(ScrollRectのvertical(holizontal)NormalizedPositionを良い感じに変更する)みたいなことがやりたい場合に便利です。
お試しあれ~
-
InputFieldにはOnFocus的なイベントが存在せず毎フレーム
isFocused
を見る。 みたいな処理が必要だった(はず) ↩