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>
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.
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!
La solution que j'ai fini par utiliser et dont je suis satisfait est:
- Suppression de
Keyboard.disableScroll(true);
- en utilisant un
<input type="text">
régulier au lieu de<ion-input type="text">
Fonctionne parfaitement maintenant!
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);
});
}
}