В Ionic 2, как плавать элемент над клавиатурой, когда клавиатура показывает?
Я хочу, чтобы панель ввода сообщения плавала над клавиатурой, когда отображается клавиатура, но похоже, что нет директивы для подключения клавиатуры (как v1) в Ionic 2 еще (возможно в работах?). Есть ли альтернатива/обходной путь?
Текущее поведение:
![17e1422aab4f42b38cfe582064ca35d09a511df6.PNG]()
![ab8ac73b7e8c3958b262d02a601b64fe2f772779.PNG]()
Требуемое поведение:
![d74b3624a4e88353ba644224642a592b49a2ef55.PNG]()
Вот код строки ввода моего сообщения:
<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>
Ответы
Ответ 1
Я нашел решение, которое работает для меня на IOS.
Когда вы просматриваете <ion-item>
с <ion-input>
в браузере (отладка использует Safari для IOS), вы можете обнаружить, что ионный генерирует <div class='input-cover'>
, который имеет стиль position: absolute;
.
Напишите CSS, который переопределяет это, как показано ниже
.input-cover {
position: static;
}
Это помогло, и теперь, когда вы фокусируетесь на поле ввода, он прокручивается в поле зрения и больше не скрывается под клавиатурой, и все это работает маслянисто.
Ответ 2
Мне также нужно было это реализовать. Я сделал это, и он отлично работает.
В первую очередь вам нужно использовать клавиатуру плагинов 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, и теперь он работает отлично (даже если вы поворачиваете экранный/альбомный режим экрана), вход всегда плавает над клавиатурой, как в родных приложениях:)
Я надеюсь, что это поможет вам!
Ответ 3
Решение, которое я закончил, и я удовлетворен тем, что:
- Удаление
Keyboard.disableScroll(true);
- Используя обычный
<input type="text">
вместо <ion-input type="text">
Теперь работает отлично!
Ответ 4
У меня была эта проблема с 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 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);
});
}
}