web-dev-qa-db-ja.com

Ionic 2、キーボードが表示されたときにキーボードの上に要素をフロートさせる方法は?

キーボードが表示されるときにメッセージ入力バーをキーボードの上に浮かせたいが、 keyboard-attach directivelike v1 )in Ionic 2まだ( 作業中かもしれません ?)。代替/回避策はありますか?

現在の動作:

望んだ行動:

メッセージ入力バーのコードは次のとおりです。

<ion-toolbar position="bottom" *ngIf="userIsAdmin">

    <form (ngSubmit)="onSubmit(f)" #f="ngForm" class="message-form">

        <ion-badge class="message-form-badge">Admin</ion-badge>

        <ion-input type="text" placeholder="Type a message..." ngControl="messageInput"></ion-input>

        <button type="submit" small class="message-form-button">Send <ion-icon name="send"></ion-icon></button>

    </form>

</ion-toolbar>
21
nunoarruda

IOSで動作するソリューションを見つけました。

<ion-item> with <ion-input>ブラウザ(デバッグではSafari for IOSを使用)では、ionicが<div class='input-cover'>スタイルはposition: absolute;

これを以下のようにオーバーライドするCSSを記述します

.input-cover {
  position: static;
}

これは私のためのトリックでしたが、入力フィールドにフォーカスすると、スクロールして表示され、キーボードの下に隠れなくなり、すべてがスムーズに動作します。

32
Anees.jsdev

これも実装する必要がありました。私はそれをやったし、完璧に動作します。

まず、cordovaプラグインキーボードを使用する必要があります。また、開始時にcordova.plugins.Keyboard.disableScroll(true);を呼び出して、キーボードがビューを押し上げないようにします。 2番目は、キーボードショーとキーボードの非表示イベントをハンドラーでリッスンする必要があります。

cordova.plugins.Keyboard.disableScroll(true);
                    window.addEventListener('native.keyboardshow', this.dispatchMe);
                    window.addEventListener('native.keyboardhide', this.dispatchMeHide);

    dispatchMe(e) {
        var event = new CustomEvent('keyboardShown');
        event['keyboardHeight'] = e.keyboardHeight;
        document.dispatchEvent(event);
    }

    dispatchMeHide() {
        var event = new CustomEvent('keyboardShown');
        event['closed'] = true;
        document.dispatchEvent(event);
    }

このようなイベントからオブザーバブルを作成できるよりも:

this.keyboardObservable = Observable.fromEvent(document, 'keyboardShown');

あなたがそのオブザーバブルを聞くことができるよりも。キーボードが開いている場合は、メッセージが表示されるコンテナの高さを変更します。基本的には、キーボードの高さ分だけ低くする必要があります。ここに私がそれをした方法があります

this.chatService.keyboardObservable
            .subscribe(data => {
                if (data.closed) {
                    this.sectionHeight = 85 + '%';
                    this.inputBottom = 0 + '%';
                }
                else {
                    this.docHeight = document.body.clientHeight;
                    this.sectionHeight = ((this.docHeight - data.keyboardHeight - (document.getElementById('toptoolbar').clientHeight + document.getElementById('inputchat').clientHeight)) / this.docHeight) * 100 + '%';
                    this.inputBottom = data.keyboardHeight / this.docHeight * 100 + '%';
                }

            });

そして、このようなngStyleでこれらのプロパティを変更します

[ngStyle]="{'height': sectionHeight}"

Chatappにもこれが必要でしたが、今では完全に機能します(画面のポートレート/ランドスケープモードを回転させても)、入力は常にネイティブアプリと同じようにキーボードの上に浮かんでいます:)

これがお役に立てば幸いです!

5
Denko Mancheski

私が最終的に使用したソリューションと私が満足しているものは次のとおりです。

  1. Keyboard.disableScroll(true);を削除しています
  2. <input type="text">の代わりに通常の<ion-input type="text">を使用する

今完璧に動作します!

2
nunoarruda

Androidでこの問題が発生していたため、個々のコンポーネントに配置できるサービスメソッドを作成しました。 <ion-input>タグ内で<ion-content>フィールドを使用することに基づいています。

これは、setScrollTopクラスに追加されたContentメソッドを利用します。

サービス

export class KeyboardService {

    autoKeyboardScroll(content:Content, scrollBackAfterKeyboardClose?:boolean) {
        if (!content) {
            return;
        }
        var previousScrollTop = null;
        function onKeyboardShow(e) {
            // if the content no longer exists, stop the listener
            if (removeListenersForMissingContent()) {
                return;
            }
            previousScrollTop = content.getScrollTop();
            // find the input that's currently in focus
            var focusedElement = document.activeElement;
            if (focusedElement && ['INPUT', 'TEXTAREA'].indexOf(focusedElement.tagName)!==-1) {
                // determine the total offset between the top of the "ion-content" and this element.
                // we will do this by climbing up the dom until we reach the "ion-content"
                var offsetTop = focusedElement.offsetTop + focusedElement.scrollHeight;
                var parentEl = focusedElement.offsetParent;
                while (parentEl && parentEl.tagName!=='ION-CONTENT') {
                    offsetTop += parentEl.offsetTop;
                    parentEl = parentEl.offsetParent;
                }
                // we want to move the input so that the bottom of the focused input is just above the keyboard
                var contentDimensions = content.getContentDimensions();
                var newScrollTop = offsetTop - (contentDimensions.contentHeight - focusedElement.scrollHeight);
                content.setScrollTop(newScrollTop);
            }
        }
        function onKeyboardHide(e) {
            // if the content no longer exists, stop the listener
            if (removeListenersForMissingContent()) {
                return;
            }
            // set the scroll top back to the initial position, if requested
            if (scrollBackAfterKeyboardClose) {
                content.setScrollTop(previousScrollTop);
            }
        }
        function removeListenersForMissingContent() {
            // if there is no content, remove the keyboard listeners
            if (!content || content.getContentDimensions().contentHeight===0) {
                window.removeEventListener('native.keyboardshow', onKeyboardShow);
                window.removeEventListener('native.keyboardhide', onKeyboardHide);
                return true;
            }
        }
        // setup listeners
        window.addEventListener('native.keyboardshow', onKeyboardShow);
        window.addEventListener('native.keyboardhide', onKeyboardHide);
    }
}

成分

@Component({
    template: `<ion-content>
        <ion-list>
            <ion-item>
                <div style="height: 400px"></div>
            </ion-item>
            <ion-item>
                <ion-label>Field 1</ion-label>
                <ion-input type="text"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label>Field 2</ion-label>
                <ion-input type="text"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label>Field 3</ion-label>
                <ion-input type="text"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label>Field 4</ion-label>
                <ion-input type="text"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label>Field 5</ion-label>
                <ion-input type="text"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label>Field 6</ion-label>
                <ion-input type="text"></ion-input>
            </ion-item>
        </ion-list>
    </ion-content>`
})
export class MyPage {
    @ViewChild(Content) content: Content;

    constructor(private: keyboardService: KeyboardService) {}

    // add the keyboard scroll action to this page. this is added after the view has been created,
    // so the content element will be avaialble.
    ionViewDidEnter() {

        // timeout seems to be required, to ensure that the content child is available
        setTimeout(() => {
            // set the keyboard to auto-scroll to the focused input, when it opens
            this.keyboardService.autoKeyboardScroll(this.content);
        });
    }
}
1
Dustin