From 570b3c05a28b2bcce7ea4d6b325f1af5cfb3296a Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 12 May 2020 13:54:14 +0200 Subject: [PATCH 1/2] MOBILE-3422 tabs: Fix grey bar on iOS when tabs are hidden --- src/components/ion-tabs/ion-tabs.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ion-tabs/ion-tabs.scss b/src/components/ion-tabs/ion-tabs.scss index 523e1dd53..e64b20c00 100644 --- a/src/components/ion-tabs/ion-tabs.scss +++ b/src/components/ion-tabs/ion-tabs.scss @@ -44,7 +44,7 @@ ion-app.app-root core-ion-tabs { } } - .tabbar[hidden] + .tabcontent { + .tabbar[hidden] + .tabcontent, &.tabbar-hidden .tabcontent { width: 100%; core-ion-tab { @include position(0, 0, 0, 0); From 9c11e753e75c18fb999c1cf262adaaa5d2382c62 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 13 May 2020 10:05:04 +0200 Subject: [PATCH 2/2] MOBILE-3422 tabs: Keep tabs on tablet when keyboard open --- src/components/ion-tabs/ion-tabs.ts | 7 ++++ src/core/mainmenu/pages/menu/menu.ts | 34 ++++++++++++++--- src/core/mainmenu/providers/mainmenu.ts | 10 +++-- src/providers/app.ts | 49 ++++++++++++++++++++++++- 4 files changed, 90 insertions(+), 10 deletions(-) diff --git a/src/components/ion-tabs/ion-tabs.ts b/src/components/ion-tabs/ion-tabs.ts index da3c1e4f2..bd6c6afab 100644 --- a/src/components/ion-tabs/ion-tabs.ts +++ b/src/components/ion-tabs/ion-tabs.ts @@ -388,4 +388,11 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy { } } } + + /** + * @inheritdoc + */ + setTabbarHidden(tabbarHidden: boolean): void { + // Don't hide the tab bar, we'll do it via CSS if needed. + } } diff --git a/src/core/mainmenu/pages/menu/menu.ts b/src/core/mainmenu/pages/menu/menu.ts index c444675b4..067689bba 100644 --- a/src/core/mainmenu/pages/menu/menu.ts +++ b/src/core/mainmenu/pages/menu/menu.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Component, OnDestroy, ViewChild, ChangeDetectorRef } from '@angular/core'; -import { IonicPage, NavController, NavParams } from 'ionic-angular'; +import { IonicPage, NavController, NavParams, Platform } from 'ionic-angular'; import { CoreAppProvider } from '@providers/app'; import { CoreSitesProvider } from '@providers/sites'; import { CoreEventsProvider } from '@providers/events'; @@ -45,13 +45,21 @@ export class CoreMainMenuPage implements OnDestroy { protected pendingRedirect: any; protected urlToOpen: string; protected mainMenuId: number; + protected keyboardObserver: any; @ViewChild('mainTabs') mainTabs: CoreIonTabsComponent; - constructor(private menuDelegate: CoreMainMenuDelegate, private sitesProvider: CoreSitesProvider, navParams: NavParams, - private navCtrl: NavController, private eventsProvider: CoreEventsProvider, private cdr: ChangeDetectorRef, - private mainMenuProvider: CoreMainMenuProvider, private linksDelegate: CoreContentLinksDelegate, - private linksHelper: CoreContentLinksHelperProvider, private appProvider: CoreAppProvider) { + constructor(protected menuDelegate: CoreMainMenuDelegate, + protected sitesProvider: CoreSitesProvider, + navParams: NavParams, + protected navCtrl: NavController, + protected eventsProvider: CoreEventsProvider, + protected cdr: ChangeDetectorRef, + protected mainMenuProvider: CoreMainMenuProvider, + protected linksDelegate: CoreContentLinksDelegate, + protected linksHelper: CoreContentLinksHelperProvider, + protected appProvider: CoreAppProvider, + protected platform: Platform) { this.mainMenuId = this.appProvider.getMainMenuId(); @@ -110,6 +118,21 @@ export class CoreMainMenuPage implements OnDestroy { window.addEventListener('resize', this.initHandlers.bind(this)); + if (this.platform.is('ios')) { + // In iOS, the resize event is triggered before the keyboard is opened/closed and not triggered again once done. + // Init handlers again once keyboard is closed since the resize event doesn't have the updated height. + this.keyboardObserver = this.eventsProvider.on(CoreEventsProvider.KEYBOARD_CHANGE, (kbHeight) => { + if (kbHeight === 0) { + this.initHandlers(); + + // If the device is slow it can take a bit more to update the window height. Retry in a few ms. + setTimeout(() => { + this.initHandlers(); + }, 250); + } + }); + } + this.appProvider.setMainMenuOpen(this.mainMenuId, true); } @@ -221,5 +244,6 @@ export class CoreMainMenuPage implements OnDestroy { this.redirectObs && this.redirectObs.off(); window.removeEventListener('resize', this.initHandlers.bind(this)); this.appProvider.setMainMenuOpen(this.mainMenuId, false); + this.keyboardObserver && this.keyboardObserver.off(); } } diff --git a/src/core/mainmenu/providers/mainmenu.ts b/src/core/mainmenu/providers/mainmenu.ts index b10d186f5..379c849ae 100644 --- a/src/core/mainmenu/providers/mainmenu.ts +++ b/src/core/mainmenu/providers/mainmenu.ts @@ -14,6 +14,7 @@ import { Injectable } from '@angular/core'; import { NavController } from 'ionic-angular'; +import { CoreApp } from '@providers/app'; import { CoreLangProvider } from '@providers/lang'; import { CoreSitesProvider } from '@providers/sites'; import { CoreUtilsProvider } from '@providers/utils/utils'; @@ -54,8 +55,10 @@ export class CoreMainMenuProvider { static ITEM_MIN_WIDTH = 72; // Min with of every item, based on 5 items on a 360 pixel wide screen. protected tablet = false; - constructor(private langProvider: CoreLangProvider, private sitesProvider: CoreSitesProvider, - protected menuDelegate: CoreMainMenuDelegate, protected utils: CoreUtilsProvider) { + constructor(protected langProvider: CoreLangProvider, + protected sitesProvider: CoreSitesProvider, + protected menuDelegate: CoreMainMenuDelegate, + protected utils: CoreUtilsProvider) { this.tablet = window && window.innerWidth && window.innerWidth >= 576 && window.innerHeight >= 576; } @@ -219,7 +222,8 @@ export class CoreMainMenuProvider { * @return Tabs placement including side value. */ getTabPlacement(navCtrl: NavController): string { - const tablet = window && window.innerWidth && window.innerWidth >= 576 && window.innerHeight >= 576; + const tablet = window && window.innerWidth && window.innerWidth >= 576 && (window.innerHeight >= 576 || + ((CoreApp.instance.isKeyboardVisible() || CoreApp.instance.isKeyboardOpening()) && window.innerHeight >= 200)); if (tablet != this.tablet) { this.tablet = tablet; diff --git a/src/providers/app.ts b/src/providers/app.ts index 8f0625765..a1dfea865 100644 --- a/src/providers/app.ts +++ b/src/providers/app.ts @@ -143,6 +143,8 @@ export class CoreAppProvider { protected logger; protected ssoAuthenticationPromise: Promise; protected isKeyboardShown = false; + protected _isKeyboardOpening = false; + protected _isKeyboardClosing = false; protected backActions = []; protected mainMenuId = 0; protected mainMenuOpen: number; @@ -179,7 +181,7 @@ export class CoreAppProvider { // Execute the callback in the Angular zone, so change detection doesn't stop working. zone.run(() => { document.body.classList.add('keyboard-is-open'); - this.isKeyboardShown = true; + this.setKeyboardShown(true); // Error on iOS calculating size. // More info: https://github.com/ionic-team/ionic-plugin-keyboard/issues/276 . events.trigger(CoreEventsProvider.KEYBOARD_CHANGE, data.keyboardHeight); @@ -189,10 +191,24 @@ export class CoreAppProvider { // Execute the callback in the Angular zone, so change detection doesn't stop working. zone.run(() => { document.body.classList.remove('keyboard-is-open'); - this.isKeyboardShown = false; + this.setKeyboardShown(false); events.trigger(CoreEventsProvider.KEYBOARD_CHANGE, 0); }); }); + this.keyboard.onKeyboardWillShow().subscribe((data) => { + // Execute the callback in the Angular zone, so change detection doesn't stop working. + zone.run(() => { + this._isKeyboardOpening = true; + this._isKeyboardClosing = false; + }); + }); + this.keyboard.onKeyboardWillHide().subscribe((data) => { + // Execute the callback in the Angular zone, so change detection doesn't stop working. + zone.run(() => { + this._isKeyboardOpening = false; + this._isKeyboardClosing = true; + }); + }); this.platform.registerBackButtonAction(() => { this.backButtonAction(); @@ -387,6 +403,24 @@ export class CoreAppProvider { return this.platform.is('ios'); } + /** + * Check if the keyboard is closing. + * + * @return Whether keyboard is closing (animating). + */ + isKeyboardClosing(): boolean { + return this._isKeyboardClosing; + } + + /** + * Check if the keyboard is being opened. + * + * @return Whether keyboard is opening (animating). + */ + isKeyboardOpening(): boolean { + return this._isKeyboardOpening; + } + /** * Check if the keyboard is visible. * @@ -529,6 +563,17 @@ export class CoreAppProvider { } } + /** + * Set keyboard shown or hidden. + * + * @param Whether the keyboard is shown or hidden. + */ + protected setKeyboardShown(shown: boolean): void { + this.isKeyboardShown = shown; + this._isKeyboardOpening = false; + this._isKeyboardClosing = false; + } + /** * Set a main menu as open or not. *