ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.1k stars 13.51k forks source link

Auto hide tabs when keyboard is open #7047

Closed RaymondAtivie closed 7 years ago

RaymondAtivie commented 8 years ago

When the keyboard is opened in a tabs page (position=bottom), the tabs appear on top of the keyboard.

The expected behavior is to hide the tabs when the keyboard is visible

Steps to reproduce:

  1. Create a starter tabs template
  2. Include an ion-input in the page
  3. Run it on a device and focus on the input element

Maybe a CSS class can be added to the page when the keyboard is open (.keyboard-is-open) so that the behavior can be controlled

This issue is for Ionic 2

Cordova CLI: 5.2.0 Gulp version: CLI version 3.9.0 Gulp local: Local version 3.9.1 Ionic Framework Version: 2.0.0-beta.9 Ionic CLI Version: 2.0.0-beta.30 Ionic App Lib Version: 2.0.0-beta.16 OS: Node Version: v4.3.2

mpaland commented 8 years ago

Yeah, I assume you're under Android. The old keyboard problem...

I saw a talk on PhoneGap conf of @tlancina about the keyboard and it seems to be a pretty hard issue in general! I can confirm that the bottom tab bar is pushed up upon opening the keyboard in my app under Android, too. But much more worse is covering input fields which are near the bottom. Tim said, one should try to avoid that, but unfortunately there are long lists to edit in my project. I have postponed the whole keyboard topic to wait and see how it plays out in ionic.

Besides, @tlancina, is there a best practice tutorial about using the keyboard in ionic (integrating the ionic keyboard plugin, init/setting event handlers)?

tlaverdure commented 8 years ago

I am experiencing this issue as well.

masimplo commented 8 years ago

We are having the same issue in our project too. Any plans regarding this?

covveadmin commented 8 years ago

Hey guys, also feeling the pain - any news by any chance?

theromis commented 8 years ago

also need this great feature, tabs and may be even header nice to be able to hide.

masimplo commented 8 years ago

@jgw96 I noticed you added the enhancement label on this. Since native apps do no behave the same (moving tabs above the keyboard) and the tabs are also limit the actual content real estate to just a couple lines, especially on smaller phones, shouldn't this be consider a more serious issue?

bvx89 commented 8 years ago

For people looking for a temporary solution, here's what I did:

TabsComponent constructor:

platform.ready().then(() => {
            Keyboard.onKeyboardShow().subscribe(() => {
                document.body.classList.add('keyboard-is-open');
            });

            Keyboard.onKeyboardHide().subscribe(() => {
                document.body.classList.remove('keyboard-is-open');
            });
});

Inside the CSS:

body.keyboard-is-open ion-tabbar {
  display: none;
}

body.keyboard-is-open scroll-content {
  margin-bottom: 0 !important;
}

This won't work if you have multiple tabs on a page, but I guess you can select them with your CSS directly.

I'm currently running Ionic beta 11

RaymondAtivie commented 8 years ago

any update on this?

RaymondAtivie commented 8 years ago

@bvx89 Thanks. For the sake of those on Rc0 there's a slight change on the css

body.keyboard-is-open .tabbar {
  display: none;
}

body.keyboard-is-open .scroll-content {
  margin-bottom: 0 !important;
}

No official solution yet tho

jeanbaptistevilain commented 7 years ago

Just to mention that enabling Fullscreen mode on Android also fixes this issue for me. This can be done by setting <preference name="Fullscreen" value="true" /> in config.xml, and optionally adding cordova-plugin-fullscreen if you're using a cordova android platform older than v5.0.0.

masimplo commented 7 years ago

Is this going to be fixed in the next version along with the rest of keyboard issues that are going to be fixed (read something stating that about keyboard issues in another thread) or has this fallen between the cracks?

finalxcode commented 7 years ago

@RaymondAtivie i have same issue, Is this going to be fixed in the next version?

helderdb commented 7 years ago

It's not working for me in RC3. the onKeyboardShow() is never fired...

Majorhe commented 7 years ago

+1, i have same issue.

Cordova CLI: 6.3.1 Ionic CLI Version: 2.1.8 Ionic App Lib Version: 2.1.4 ios-deploy version: Not installed ios-sim version: Not installed OS: Windows 8.1 Node Version: v6.4.0 Xcode version: Not installed

payneBrandon commented 7 years ago

I have this same issue, and the workaround posted by @RaymondAtivie isn't working quite right. the tabs are no longer visible, but there appears to be a top border still visible. Anyone else have this issue? I've tried adding box-shadow: none; border-top: none; and still end up with the same top border visible from the tabbar. Any ideas?

theromis commented 7 years ago

I've solved this issue by turning ion-content option fullscreen="true" and setting hidden style for tabbar

      var tabbars =     document.getElementsByClassName('tabbar');
      for(var i=0; i<tabbars.length; i++) {
        var node = <HTMLElement>tabbars[i];
        node.style.display = hide === true && 'none' || 'block';
      }
payneBrandon commented 7 years ago

I've tried this and still have the same top border showing even though the tabbar is set to display false.

theromis commented 7 years ago

@payneBrandon I'm hiding top bar <ion-header *ngIf="isShowHeader()">

payneBrandon commented 7 years ago

My ion-tab is at the bottom, so hiding the header doesn't affect it much. I've attached a screenshot of what I'm talking about. The keyboard is shown, the tabs at the bottom are hidden, but it still appears that there is some top boarder line that stays in place if i scroll around. 20170113_102807

theromis commented 7 years ago

this bar looks like a part of the form can you share your html code?

payneBrandon commented 7 years ago

Finally figured it out. I didn't have to worry about a header since my tabs are on the bottom, BUT I did need to look to the footer (duh!). I applied a conditional class to the footer to hide it if the body has the keyboard-is-open class and BAM, back in business. Thanks for the help!

theromis commented 7 years ago

@payneBrandon good luck

royipressburger commented 7 years ago

Would like to see that feature as well. Also I think that ion-footer should support visibility on keyboard open/close

theblindprophet commented 7 years ago

I have made a simple fix (of course not ideal). The .scroll-content has a margin-bottom of 56px, the same height has the tabs. I check for the key board:

public keyboardCheck() {
        return this.keyboard.isOpen();
}

and then attach this class to ion-content, a parent of .scroll-content:

.keyboard-open .scroll-content {
    margin-bottom: 0px !important;
}

and add this to ion-content:

<ion-content padding [ngClass]="{'keyboard-open': keyboardCheck()}">

I also hid the tabs when the keyboard is open using the same method in tabs.html:

<ion-tabs [ngClass]="{'remove-tabs': keyboardCheck()}">

.remove-tabs .tabbar {
    display: none;
}

I did this only for the page which I needed the fix.

Working in both iOS and Android.

TechSnake commented 7 years ago

SOLVED

this a proper solution except css marked.

import { Component } from '@angular/core';
import  {Keyboard} from 'ionic-native'
import { HomePage } from '../home/home';
import { AboutPage } from '../about/about';
import { ContactPage } from '../contact/contact';

@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {
  // this tells the tabs component which Pages
  // should be each tab's root Page
  tab1Root: any = HomePage;
  tab2Root: any = AboutPage;
  tab3Root: any = ContactPage;
  valueforngif=true;

  constructor(public keyboard:Keyboard) { }
   ionViewDidEnter(){
     Keyboard.onKeyboardShow().subscribe(()=>{this.valueforngif=false})
     Keyboard.onKeyboardHide().subscribe(()=>{this.valueforngif=true})
}}

this my tabs.html

```

<ion-tabs *ngIf="valueforngif"> <ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"> <ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle" [tabsHideOnSubPages]="true"> <ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts">

Slavrix commented 7 years ago

nice @efnan34 , though you shouldnt need to provide it in the constructor.

Killmore commented 7 years ago

This is causing my keyboard to close automatically upon opening it... Is this due to the focus returning to the tabs to hide them which in turn makes the keyboard close?

ionViewDidEnter(){
    Keyboard.onKeyboardShow().subscribe(()=>{this.valueforngif=false})
    Keyboard.onKeyboardHide().subscribe(()=>{this.valueforngif=true})
}
aoathout commented 7 years ago

@bvx89 Your solution is the only one I could get to work with Ionic 2.1.0. There is a bug logged for ionic-native and changes not being detected so the other work arounds didn't work for me. Looking forward to an official fix for this

mazyvan commented 7 years ago

I'm having the same problem @Killmore isn't there any official solution to this yet?

TechSnake commented 7 years ago

Hello The solution above runs on Ionic 2.1.0 as well but a better result [hidden] attrb can used in stead of *ngif.I m using this solution at my project it works fine

Have a nice day

cozzbie commented 7 years ago

Above will cause a flicker on some android devices and really is a bad option.

Gopimaruvada commented 7 years ago

This will Work .. try this

var originalHeight = document.documentElement.clientHeight; var originalWidth = document.documentElement.clientWidth; $(window).resize(function() { // Control landscape/portrait mode switch if (document.documentElement.clientHeight == originalWidth && document.documentElement.clientWidth == originalHeight) { originalHeight = document.documentElement.clientHeight; originalWidth = document.documentElement.clientWidth; } // Check if the available height is smaller (keyboard is shown) so we hide the footer. if (document.documentElement.clientHeight < originalHeight) { $('.footer').hide(); } else { $('.footer').show(); } });

kabus202 commented 7 years ago

This is how i solved this issue:

tab.ts

import { Component, ElementRef, Renderer, ViewChild } from '@angular/core';
import { Events, Tabs } from 'ionic-angular';

import { AboutPage } from '../about/about';
import { ContactPage } from '../contact/contact';
import { HomePage } from '../home/home';

@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {
  @ViewChild('myTabs') tabRef: Tabs;
  mb: any;
  tab1Root = HomePage;
  tab2Root = AboutPage;
  tab3Root = ContactPage;

  constructor(private elementRef: ElementRef, private renderer: Renderer, private event: Events) {

  }
  ionViewDidLoad() {
    let tabs = this.queryElement(this.elementRef.nativeElement, '.tabbar');
    this.event.subscribe('hideTabs', () => {
      this.renderer.setElementStyle(tabs, 'display', 'none');
      let SelectTab = this.tabRef.getSelected()._elementRef.nativeElement;
      let content = this.queryElement(SelectTab, '.scroll-content');
      this.mb = content.style['margin-bottom'];
      this.renderer.setElementStyle(content, 'margin-bottom', '0')
    });
    this.event.subscribe('showTabs', () => {
      this.renderer.setElementStyle(tabs, 'display', '');
      let SelectTab = this.tabRef.getSelected()._elementRef.nativeElement;
      let content = this.queryElement(SelectTab, '.scroll-content');
      this.renderer.setElementStyle(content, 'margin-bottom', this.mb)
    })
  }
  queryElement(elem: HTMLElement, q: string): HTMLElement {
    return <HTMLElement>elem.querySelector(q);
  }
}

specific page.ts

import { Component } from '@angular/core';
import { NavController, Events } from 'ionic-angular';

import { Keyboard } from '@ionic-native/keyboard';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController, private event: Events, private keyboard: Keyboard) {

  }
  ionViewDidLoad() {
    this.keyboard.onKeyboardShow().subscribe(() => this.event.publish('hideTabs'));
    this.keyboard.onKeyboardHide().subscribe(() => this.event.publish('showTabs'));
  }
}

credits to dPary

cozzbie commented 7 years ago

I really hope you all are doing proper device testing because all of these solutions that hide tabs cause the view to re-render on devices which will cause a very visible flicker and in some cases crashes. Anyways, all the best.

mazyvan commented 7 years ago

Yeah, I'm with @cozzbie all of this are just some hacks. We need a real official solution by the team @ionitron @manucorporat

Removed-5an commented 7 years ago

+1 We need an official solution, none of these fixes are ideal for production use.

TechSnake commented 7 years ago

Current version of ionic does it on its own

21 Nis 2017 17:12 tarihinde "Ruben Callewaert" notifications@github.com yazdı:

+1 We need an official solution, none of these fixes are ideal for production use.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/driftyco/ionic/issues/7047#issuecomment-296201358, or mute the thread https://github.com/notifications/unsubscribe-auth/AVskkCpgFZZRbrd56ILc5nIPZICRTclUks5ryLlCgaJpZM4I-H1S .

vazad28 commented 7 years ago

Is this really taken care of. I still see the tab bar. Running latest version as on this writing ionic-angular 3.2.0.

TechSnake commented 7 years ago

İt was working very well with 2.x.x version but now i checked 3.x.x version there is somethings wrong .it doesnt hide what you want on the screen until typing on keyboard .Unfortunality we have fınd other solution ör downgraded ur ionic version to any 2.x.x

12 May 2017 ÖÖ 3:32 tarihinde "vazad28" notifications@github.com yazdı:

Is this really taken care of. I still see the tab bar. Running latest version as on this writing ionic-angular 3.2.0.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/driftyco/ionic/issues/7047#issuecomment-300952251, or mute the thread https://github.com/notifications/unsubscribe-auth/AVskkNkEdzsMkkrhGW0l9OUW2BKly-PSks5r46ingaJpZM4I-H1S .

cozzbie commented 7 years ago

Just a thought here. Hiding the tabs using any of the hacks above causes the view to refresh on devices, so how about we just drop the height of the tab zone to zero instead of hiding? Just a thought but I am too involved right now to try it out.

viking2917 commented 7 years ago

+1 for an official fix! The "display:none" approaches cause unacceptable flickering, and the tabs render once then disappear...looks gross and hacky. (anybody have any ideas how to get rid of the flicker? I'm not above a hack if it looks good to the user)

Floyd1256 commented 7 years ago

Anything new regarding this issue? still waiting for an official fix before I lose hope and start implementing something that would affect the quality of the UI

Khalid-Nowaf commented 7 years ago

@patrickmcd, The Lord of The Thumbs Down, just wondering have you try to quit this habit?

cozzbie commented 7 years ago

@viking2917 you could try the hack I suggested and try forcing the tabs height to zero. That might work. I haven't tried it yet though.

webberig commented 7 years ago

Unfortunately hiding the tabs with CSS will cause a number of problems. Ionic calculates a few values such as margin on ion-content and takes into account the presence of the tabs (which are hidden).

We've had to remove the solution because some positioning problems with other components occured.

WhatsThatItsPat commented 7 years ago

@Khalid-Nowaf I simply don't appreciate spam comments that sap time away from the Ionic team and away from the ~2000 watchers of this repo.

@Floyd1256's comment is inconsiderate spam. It adds nothing to the conversation. It is just another "plus one / are we there yet" comment which only serves to fill our inboxes.

My downvotes are attempts to nudge others toward more considerate behavior. Before commenting, we should remember that we are having a conversation with ~2000 people whose time is precious. We shouldn't treat this space as flippantly as we would a personal IM chat with friends. We should ask ourselves whether our comment will help or hinder others, whether it advances the conversation or is just noise, whether it is truly necessary to say or could better be voiced with a Github reaction, and whether it will accelerate or slow down development.

masimplo commented 7 years ago

There seems to be a branch addressing this issue along with some others https://github.com/ionic-team/ionic/tree/keyboard-fixes This commit in particular looks very promising

RicardoBer commented 7 years ago

I do not have courage to go more than ionic v1.

I make this patch (I put in a the controller of affected view, as I only have one with this combo).

/ HACK Al mostrar el teclado el tabbar se pone encima de él en android/ var bottom_stored=0; window.addEventListener('native.keyboardshow', function (e) { angular.element(document.getElementsByClassName('tab-nav')).addClass('hide'); bottom_stored = angular.element(document.getElementsByClassName('has-tabs')).css('bottom'); angular.element(document.getElementsByClassName('has-tabs')).css('bottom','0px'); $scope.$apply(); }); window.addEventListener('native.keyboardhide', function (e) { angular.element(document.getElementsByClassName('tab-nav')).removeClass('hide'); angular.element(document.getElementsByClassName('has-tabs')).css('bottom',bottom_stored); $scope.$apply(); }); / HACK /

this works

Jatapiaro commented 7 years ago

In my case this only happens when I'm using android, the best solution is change a property on the android tag in config.xml

`

` Just simple add the following lines, so the android build in the AndroidManifest.xml have the adjustPan in android:windowSoftInputMode, this will cause that the keyboard overlays all the content instead of pushing the screen up.
pablogarciamiranda commented 6 years ago

For the approach of @Jatapiaro explained above, I have installed the following cordova plugin:

cordova plugin add cordova-custom-config

Then I have just added the following to my config.xml

<platform name="android">
    <preference name="android-manifest/application/activity/@android:windowSoftInputMode" value="adjustPan" />
    ...
</platform>

Working on Android & iOS