キーボードが表示されるときにメッセージ入力バーをキーボードの上に浮かせたいが、 keyboard-attach directive ( like 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>
IOSで動作するソリューションを見つけました。
<ion-item>
with <ion-input>
ブラウザ(デバッグではSafari for IOSを使用)では、ionicが<div class='input-cover'>
スタイルはposition: absolute;
。
これを以下のようにオーバーライドするCSSを記述します
.input-cover {
position: static;
}
これは私のためのトリックでしたが、入力フィールドにフォーカスすると、スクロールして表示され、キーボードの下に隠れなくなり、すべてがスムーズに動作します。
これも実装する必要がありました。私はそれをやったし、完璧に動作します。
まず、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にもこれが必要でしたが、今では完全に機能します(画面のポートレート/ランドスケープモードを回転させても)、入力は常にネイティブアプリと同じようにキーボードの上に浮かんでいます:)
これがお役に立てば幸いです!
私が最終的に使用したソリューションと私が満足しているものは次のとおりです。
Keyboard.disableScroll(true);
を削除しています<input type="text">
の代わりに通常の<ion-input type="text">
を使用する今完璧に動作します!
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);
});
}
}