2016-04-19 117 views
19

我想讓我的消息輸入欄在鍵盤顯示時漂浮在鍵盤上方,但它看起來像Ionic 2中沒有keyboard-attach directivelike v1)(maybe in the works?)。有其他解決方法嗎?在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> 

回答

30

我發現這對我來說適用於iOS的解決方案。

當您檢查<ion-item><ion-input>在瀏覽器中(調試使用Safari爲IOS),你可以發現,離子生成<div class='input-cover'>它有風格position: absolute;

寫它覆蓋了這個如下

.input-cover { 
    position: static; 
} 

一個CSS這爲我做的伎倆,現在當你專注於一個輸入字段,它滾動到視圖中,並沒有隱藏在鍵盤下面再而這一切作品流暢。

+0

這對我來說就像一個魅力!謝謝 – user3153278

+0

這一直讓我瘋狂。非常簡單的解決方案。 – Matt

+0

答案像一個魅力工作,一直在努力與插件等..偉大的工作! – JoeriShoeby

5

我也東東代表實施這一點。我做到了,它完美地工作。

1st你需要使用cordova插件鍵盤,並且在開始時撥打 cordova.plugins.Keyboard.disableScroll(true);這樣鍵盤就不會推動你的視線了。 第二,你需要在keyboardshow和鍵盤隱藏事件,聽這樣一個處理程序:

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,現在它完美的作品(即使你旋轉屏幕縱向/風景模式),輸入總是漂浮在鍵盤之上,就像在本機應用:)

我希望這會幫助你!

+2

您還可以縮短此時間並直接發送到處理程序,而不是分派自定義事件並獲取監聽它們的可觀察事件。也許你可以直接從「native.keyboardshow」事件中創建觀察對象,然後把這段代碼截斷2/3 :) –

2

我結束了使用的解決方案和一個我很滿意的是:

  1. 刪除Keyboard.disableScroll(true);
  2. 使用的<ion-input type="text">

作品經常<input type="text">,而不是完美的吧!

+0

它只是在切換到純html輸入元素時起作用 –

1

我遇到了Android的這個問題,所以我創建了一個服務方法,我可以將它放入單個組件中。它基於在<ion-content>標記內使用<ion-input>字段。

這利用了Content類中添加的setScrollTop方法。

服務

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