Dans Ionic 2, Comment faire flotter un élément au-dessus du clavier lorsque le clavier s'affiche?

Je veux que ma barre de saisie de message flotte au-dessus du clavier lorsque le clavier s'affiche, mais il semble qu'il n'y ait pas de directive keyboard-attach (comme v1 ) dans Ionic 2 encore ( peut-être dans les travaux ?). Existe-t-il une alternative/solution de contournement?

Comportement Actuel:

Comportement recherché:

Voici le code de ma barre d'entrée de message:

<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
demandé sur nunoarruda 2016-04-19 03:16:16

4 réponses

J'ai trouvé une solution qui fonctionne pour moi sur IOS.

Lorsque vous inspectez le <ion-item> avec <ion-input> dans le navigateur (débogage utiliser Safari pour IOS), vous pouvez constater que ionic génère un {[3] } qui a le style position: absolute;.

Écrivez un CSS qui remplace ceci comme ci-dessous

.input-cover {
  position: static;
}

Cela a fait l'affaire pour moi Et maintenant quand vous vous concentrez sur un champ de saisie, il défile en vue et ne se cache plus sous le clavier et tout cela fonctionne en douceur.

30
répondu Anees.jsdev 2016-08-05 10:10:39

J'ai aussi besoin de mettre en œuvre cela. Je l'ai fait et cela fonctionne parfaitement.

1er vous devez utiliser cordova plugins clavier, et au début de l'appel cordova.plugins.Keyboard.disableScroll(true); ainsi, le clavier ne poussera pas votre vue vers le haut. 2ème vous devez écouter sur les événements keyboardshow et keyboard hide comme celui-ci avec les gestionnaires:

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);
    }

Que vous pouvez faire un événement observable de ce type:

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

Que vous pouvez écouter cela observable. Si le clavier est ouvert que vous modifiez la hauteur du conteneur où vos messages sont affichés. Vous devez essentiellement le rendre plus bas pour la hauteur du clavier. Voici comment je l'ai fait

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 + '%';
                }

            });

Et vous modifiez ces propriétés avec ngStyle comme ceci

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

J'en avais aussi besoin pour chatapp, et maintenant cela fonctionne parfaitement (même si vous faites pivoter l'écran en mode portrait / paysage), l'entrée flotte toujours au-dessus du clavier comme dans les applications natives:)

J'espère que cela vous aidera!

5
répondu Denko Mancheski 2016-04-22 23:35:26

La solution que j'ai fini par utiliser et dont je suis satisfait est:

  1. Suppression de Keyboard.disableScroll(true);
  2. en utilisant un <input type="text"> régulier au lieu de <ion-input type="text">

Fonctionne parfaitement maintenant!

2
répondu nunoarruda 2016-05-10 03:41:12

J'avais ce problème avec Android, donc j'ai créé une méthode de service que je pouvais mettre dans des composants individuels. Il est basé sur l'utilisation de <ion-input> champs à l'intérieur d'un <ion-content> balise.

Cela tire parti de la méthode setScrollTop qui a été ajoutée à la classe Content.

Service

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);
    }
}

Composant

@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
répondu Dustin 2016-07-08 00:56:33