Ionic-framework: Pas de remplissage pour la barre d'état (sur iOS) lors de la navigation à l'intérieur d'un modal

Créé le 21 sept. 2016  ·  45Commentaires  ·  Source: ionic-team/ionic-framework

Brève description du problème :

La barre de navigation peut chevaucher la barre d'état sur iOS, lorsqu'une nouvelle page est poussée à l'aide de NavController#push depuis l'intérieur d'un modal. Voir capture d'écran.

img_2079

Quel comportement attendez-vous ?

Comme toutes les autres barres de navigation, celle-ci devrait laisser suffisamment d'espace pour la barre d'état.

Étapes à reproduire :

  1. Ouvrez un modal.
  2. Dans le modal, appelez NavController#push avec n'importe quelle page.

Quelle version ionique ? 2

Repo qui montre un exemple de votre problème

https://github.com/zmbc/statusbar

Accédez à la liste, ouvrez un élément, puis appuyez sur "Pousser quelque chose".

Exécutez ionic info partir de l'invite du terminal/cmd : (collez la sortie ci-dessous)
Version Gulp : CLI version 3.9.1
Gulp local : version locale 3.9.1
Version du cadre ionique : 2.0.0-beta.11
Version Ionic CLI : 2.0.0-beta.32
Version de l'application Ionic Lib : 2.0.0-beta.18
version de déploiement d'ios : 1.8.6
version ios-sim : 3.1.1
OS : Mac OS X El Capitan
Version du nœud : v6.3.0
Version Xcode : Xcode 7.3.1 Version de construction 7D1014

Commentaire le plus utile

Toujours présent dans ionic-angular 3.3.0. Une manière de résoudre ce problème?

Tous les 45 commentaires

même problème ici. Je l'ai résolu en ne poussant pas la nouvelle page mais en la présentant comme un deuxième modal.

Bonjour à tous! Merci d'avoir utilisé Ionic!. Je suis heureux d'annoncer que je ne peux plus reproduire ce problème avec RC0. Merci!

Ce bug existe toujours. Ce problème ne peut être reproduit que sur un périphérique/émulateur réel. Il n'apparaîtra pas sur les navigateurs de bureau à moins que vous ne passiez { statusbarPadding: true } à la variable de configuration de IonicModule.forRoot(MyApp, config) . J'ai créé un dépôt rapide pour démontrer ce problème avec RC0 https://github.com/msalcala11/modal-padding-bug.

Même problème ici.

Peut également confirmer ce problème

oui ce problème existe toujours. s'il vous plaît rouvrir

Nous devons mieux documenter les modalités, nous avons des personnes qui travaillent dessus en ce moment.
@comfortme @royipressburger @CyrisXD @msalcala11 @zmbc Vous devez créer un nouveau ion-nav afin d'avoir la navigation dans un modal, tout comme vous le faites pour avoir la navigation dans votre application.

@Component({
  template: '<ion-nav [root]="root"></ion-nav>'
})
export class NavigationModal {
  root = ModalFirstPage;
}

// YOUR CONTENT MODAL
@Component({})
export class ModalFirstPage {
}

(...)

  presentModalChildNav() {
    this.modalCtrl.create(NavigationModal).present();
  }

cela n'a toujours pas vraiment de sens pour moi.

J'ai une page vers laquelle je vais naviguer soit à partir d'une autre page OU à partir d'un modal selon l'endroit où se trouve l'utilisateur dans l'application.

Lorsque je fais un nav.push dans le modal, il va à la page, tout se passe bien et fonctionne exactement comme je le veux. SAUF que le remplissage de la barre d'état n'est pas appliqué lorsque je navigue vers la page à partir d'un modal.

Je ne vois pas vraiment en quoi l'extrait de code ci-dessus m'aide du tout? Cela semble être une chose très simple car fonctionnellement tout fonctionne ET dans l'une des versions bêta précédentes, le remplissage de la barre d'état a également été correctement appliqué, mais cela a ensuite été interrompu à nouveau dans une version ultérieure.

Notez qu'android n'a aucun problème avec le même code, la navigation à partir d'une autre page ou d'un modal, tout est formaté correctement et fonctionne très bien, je m'attendrais à ce que ios soit le même.

Existe encore. Des hacks simples pour empêcher cela?

Appliquez le CSS suivant à ion-navbar et ion-title pour résoudre ce problème. J'utilise un ngIf * pour ne l'appliquer que si la plate-forme.is (iOS) en tant qu'Android n'en a pas besoin. Ceci est simplement remplacé par le css par défaut lors de l'ouverture à partir d'une autre page sur iOS, donc pas de problème non plus.

Notez également que toute alerte / feuille d'action / pop over que vous ouvrez à partir de la page nouvellement poussée s'ouvrira derrière la page. Vous devrez pirater la valeur du z-index pour que ces composants soient supérieurs au z-index modal afin qu'ils soient toujours au premier plan. Étant donné que ces choses devraient toujours être au top de toute façon, ce n'est pas vraiment un problème.

<ion-navbar *ngIf="globals.isIos" style="height:calc(44px + 20px); min-height:calc(44px + 20px); padding-top:20px;">
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title style="padding-top:14px !important;">{{selectedItem.name}}</ion-title>
  </ion-navbar>

Toujours avoir ce problème. Cela sera-t-il bientôt corrigé ?

@mrhirsch Il y a un problème similaire ici . Vérifiez-le. Ce n'est pas corrigé, mais @manucorporat a demandé un exemple de

@ghenry22

La façon dont vous faites ce rembourrage n'est pas une bonne façon. N'utilisez pas *ngIf pour masquer les barres de navigation en fonction des types de plate-forme. Le calcul pour le ion-content par la suite ne tiendra pas compte de la barre de navigation et fera monter tout le ion-content .

Au lieu de cela, dans le app.scss , ajoutez le CSS suivant.

.platform-ios .ios-header {
  height:calc(56px + 20px);
  min-height:calc(56px + 20px);
  padding-top:20px;
}

Ensuite, simplement dans l'en-tête dont vous avez besoin (pour moi, ce sont toutes les pages où je pousse sur la page Tab), ajoutez simplement class="ios-header" .

<ion-header>
  <ion-navbar class="ios-header">
  </ion-navbar>
</ion-header>

Beaucoup plus sec, et sans le problème ion-content . Bien sûr, si l'équipe Ionic enquêtait elle-même, nous n'aurions pas à subir cette douleur.

Pour tous ceux qui trébuchent dessus avec un popover, c'est le même problème.

Concernant la solution : ce n'est pas une bonne idée d'opter pour l'approche CSS-fix parce que vous masquez simplement quelque chose que vous ne faites pas comme prévu (même si c'est un peu un design étrange).

Une autre solution que celle évoquée par manucorporat est de travailler sur l'événementiel. Je l'ai fait comme ça et c'est très simple et propre. Déclenchez simplement un événement dans votre page modale ou popover et écoutez-le dans votre page "parent". Vous trouverez plus d'informations sur les événements ici : https://ionicframework.com/docs/api/util/Events/

@timvandijck Pouvez-vous donner un exemple ?

@kabus202 c'est un exemple avec un popover :

La page où vous lancez le popover :

@Component({
    selector: 'page-my-page',
    templateUrl: 'my-page.html'
})
export class MyPage {
    popover = null;

    constructor(public navCtrl:NavController, public popoverCtrl: PopoverController, public events: Events) {
        this.events.subscribe('nav:my-other-page', () => {
            this.navCtrl.setRoot(MyOtherPage);

            if (this.popover) {
                this.popover.dismiss();
            }
        })
    }

    toggleActionsMenu(event) {
        this.popover = this.popoverCtrl.create(PopoverContentPage);
        this.popover.present({
            ev: event
        });
    }
}

La page qui contient le contenu du popover :

@Component({
    selector: 'page-popover-content',
    templateUrl: 'popover-content.html'
})
export class PopoverContentPage {

    constructor(public events: Events) {
    }

    registerAppliance() {
        this.events.publish('nav:my-other-page');
    }
}

Oui, c'est toujours un problème. De plus, lorsque vous essayez de balayer pour revenir en arrière, cela peut parfois agir et faire apparaître la vue sous le modal. @jgw96

Toujours présent dans ionic-angular 3.3.0. Une manière de résoudre ce problème?

@manucorporat Pourriez-vous rouvrir ce problème s'il vous plaît ? Ouvrir le modal dans la page ouverte par navController.push() provoque la même situation que celle illustrée dans le premier message.

Oui merci de rouvrir

@vosecek Le problème existe, mais vous pouvez utiliser mon correctif css que j'ai posté ci-dessus. Cela fonctionne avec 3.3.

Hé les gars, consultez l' API NavController , en particulier la section intitulée Navigating from an Overlay Component (collé ci-dessous)

Notez l'utilisation de this.appCtrl.getRootNav() . Cela a très bien fonctionné pour moi, donc je suis curieux de savoir si l'utilisation de App résout ce problème pour les autres. Quoi qu'il en soit, je pensais juste que vous devriez tous savoir à ce sujet.

Navigation à partir d'un composant de superposition

import { Component } from '@angular/core';
import { App, ViewController } from 'ionic-angular';

@Component({
    template: `
    <ion-content>
      <h1>My PopoverPage</h1>
      <button ion-button (click)="pushPage()">Call pushPage</button>
     </ion-content>
    `
  })
  class PopoverPage {
    constructor(
      public viewCtrl: ViewController
      public appCtrl: App
    ) {}

    pushPage() {
      this.viewCtrl.dismiss();
      this.appCtrl.getRootNav().push(SecondPage);
    }
  }

Je suppose que la question est de savoir pourquoi ajouteriez-vous autant par-dessus la tête alors que vous pouvez simplement nav.push et que tout fonctionne parfaitement, à l'exception d'un peu de CSS que personne ne semble intéressé à corriger?

Cela me rappelle un peu la réponse d'Apple « juste le tenir différemment » aux problèmes d'antenne.

Pourquoi ce problème est clos s'il est toujours là ?

@edwinchoate cela fonctionne mais pas lorsque vous avez toujours besoin que le popover soit actif lorsque vous revenez de la page. Je ne pense pas qu'il soit possible de naviguer et de revenir à un popover comme une page normale avec le design actuel, le popover est positionné sur un calque plus élevé que toutes les pages normales, donc le rejet est requis. À moins qu'ils ne changent complètement le comportement de popover.

Comme ce bogue n'a pas été corrigé, j'ai ajouté ce code SCSS comme solution de contournement et cela a fonctionné pour moi. J'espère qu'il vous sera utile :

.toolbar-ios {
  height: 44px + $cordova-ios-statusbar-padding;
  padding-top: $cordova-ios-statusbar-padding;
}

.toolbar-title-ios {
  padding-top: $cordova-ios-statusbar-padding;
}

À tous ceux qui trébuchent encore là-dessus. @manucorporat a déjà présenté la bonne idée. Le code a juste une erreur et est quelque peu incomplet. J'ai testé cela avec Ionic 3.6.0 .

Dans la page de contenu que vous présentez en tant que modal, incluez simplement une autre classe de page wrapper avec un élément de navigation comme celui-ci :

@Component({
    template: '<ion-nav [root]="this.rootPage" [rootParams]="this.rootParams"></ion-nav>'
})
export class MyModalWrapper {
    private rootPage = MyModalContentPage;
    private rootParams;
    constructor(navParams: NavParams, private viewCtrl: ViewController) {
        this.rootParams = navParams;
        this.rootParams["data"]["closeModal"] = this.onCloseModal
    }
    onCloseModal = () => {
        this.viewCtrl.dismiss();
    }
}

Et puis modifiez votre classe de page de contenu comme ceci :

@Component({ /* ... */ })
export class MyModalContentPage {
    /* ... */
    private closeModal;
    constructor(navParams: NavParams, /* ... */) {
        this.closeModal = navParams.get("closeModal");
    }
    /* ... */
}

Vous pouvez maintenant appeler closeModal comme une fonction normale dans votre classe ou modèle.

Il ne vous reste plus qu'à remplacer MyModalContentPage par MyModalWrapper partout où vous créez et présentez le modal. Donc au lieu de :

this.modalCtrl.create(MyModalContentPage, { /* ... */ }).present();

fais ceci :

this.modalCtrl.create(MyModalWrapper, { /* ... */ }).present();

J'espère que cela t'aides.

@codemusings je l'ai fait de cette façon:

@Component({
  template: '<ion-nav [root]="root" [rootParams]="params"></ion-nav>'
})
export class MyModalWrapper {
  root = MyModalContentPage;
  params: any;

  constructor(
    public navParams: NavParams,
    viewCtrl: ViewController,
  ) {
    this.params = Object.assign({}, navParams.data, {viewCtrl: viewCtrl});
  }
}

@Component({ /* ... */ })
export class MyModalContentPage {
    /* ... */
    private viewCtrl: ViewController;
    constructor(navParams: NavParams, /* ... */) {
        this.viewCtrl = navParams.get('viewCtrl');
    }
    /* ... */
    someFunc() {
      this.viewCtrl.dismiss();
    }
}

En passant le ViewController entier, vous pouvez utiliser le même this.viewCtrl.dismiss() vous utiliseriez normalement ; aucune modification dans la page de contenu n'est nécessaire, sauf dans le constructeur.

Je suis sur Ionic 3.3.0 mais je suppose que cela fonctionnerait aussi sur la dernière version.

Mais le fait est que, fonctionnellement, cela fonctionne parfaitement tel quel et il n'y a pas besoin de tout ce code supplémentaire, juste un correctif CSS d'une seule ligne pour iOS uniquement et ce n'est même pas un problème.

@ ghenry22 Ce n'est pas tout à fait correct pour les grands écrans, par exemple l'iPad, où la page poussée est en plein écran même si le modal est petit.

Je souhaite nav.push dans un modal Just Worked. Mais je préfère le faire de cette manière plus complexe que de m'appuyer sur des correctifs CSS plus hacker.

@ghenry22 @zmbc La vue de navigation implique une pile de navigation distincte, que vous créez lors de l'ouverture d'un modal. Ceci est le chemin".

Lorsque vous appelez navCtrl.pop, cela peut créer des problèmes par inadvertance avec la navigation racine, car Ionic ne comprend pas quand vous êtes dans un modal et quand vous ne l'êtes pas.

Je n'ai pas non plus de problème avec les pages poussées sur iOS ? Je veux dire que je vais le tester à nouveau maintenant que vous l'avez mentionné pour m'assurer qu'ils restent dans les limites du modal pour moi.

Fondamentalement, si je pousse ou ouvre une page à partir d'un modal, je m'attends à ce qu'elle se charge et soit liée dans le modal.

Si je pousse ou saute sur une page normale, je m'attends à ce qu'elle se charge avec une page plein écran normale.

J'ai des pages que je peux utiliser dans les deux scénarios, donc l'ajout de code pour gérer un scénario peut causer des problèmes dans l'autre.

Si vous voulez que la page poussée à l'intérieur d'un modal s'ouvre en plein écran sur ipad, je suppose que vous devez avoir une fonction qui ferme le modal, puis pousse la page, ce qui pourrait devenir un peu désordonné à coup sûr.

@wbhob cela peut être le résultat souhaité, mais tout ce que vous avez à faire est de regarder ce ticket et les forums ioniques et le débordement de la pile pour voir la même question se poser encore et encore.

Donc, évidemment, c'est un problème d'un point de vue purement convivial pour les gens. Ce serait formidable si ionic pouvait implémenter quelque chose sous le capot pour que cela "fonctionne" alors tous les commentaires et demandes sur ce problème clos s'arrêteraient :)

Fait un PR aux docs @ghenry22

Mon pr a été fusionné! Consulter les docs modales

@ jgw96 J'espère que cela sera résolu avec Ionic4. Il est exceptionnel depuis ionic2 RC0 sans aucune action, ce qui est un peu choquant étant donné qu'il s'agit d'un simple correctif CSS, puis l'utilisation de la navigation fonctionne comme prévu, que vous soyez dans une page modale ou normale. Comme il se doit.

Cela fonctionne comme prévu, ce n'est pas un problème. Il y a des détails sur le faire dans les docs Ionic (j'ai écrit cette partie des docs)

@wbhob sauf que cela ne fonctionne pas comme prévu. Comme le montrent les nombreux fils de discussion sur le forum. Problèmes ici et sur le débordement de la pile.

La navigation fonctionne exactement comme vous l'attendriez, à l'exception du fait que la page poussée perd son statut lors du remplissage. Il s'agit d'un simple correctif CSS et ne nécessite rien de plus compliqué.

Votre solution de contournement recommandée et d'autres impliquent de fermer la superposition avant d'ouvrir la nouvelle page. Ce n'est pas une approche faisable pour mon application car je veux que l'utilisateur puisse afficher certaines informations soit à partir d'un modal OU à partir d'autres pages régulières et si la visualisation à partir d'un modal, je veux qu'il puisse revenir au modal.

Quoi qu'il en soit, j'ai publié un correctif CSS uniquement pour cela dans l'un des autres problèmes enregistrés pour cela l'autre jour, qui l'a complètement résolu pour moi en appliquant simplement les styles de page ioniques standard comme ils le seraient dans un cadre non modal.

La bonne façon de procéder consiste à créer une instance de navigation autonome à l'intérieur du modal. Votre intention est de naviguer vers des pages supplémentaires, mais lorsque vous appelez navCtrl.push, comme vous vous en doutez, il l'exécute sur la pile de navigation racine car il ne sait pas mieux. Lorsque vous le faites correctement et que vous créez une pile de navigation exclusive au modal, cela fonctionne correctement.

Oui, c'est une façon de le faire pour un scénario spécifique. En supposant que, dans votre cas d'utilisation, vous souhaitiez ignorer la superposition ouverte (modale / pop over, etc.), puis ouvrir la page. Dans ce scénario, oui, ce que vous avez dit et ce qui est indiqué dans la documentation des composants ioniques pour le contrôleur de navigation fonctionne correctement.

Je ne veux pas rejeter le modal qui est ouvert, je veux pouvoir naviguer vers une page qui affichera des informations supplémentaires, et une fois terminé, cliquez sur RETOUR pour revenir au modal à partir duquel la page a été ouverte. Ce scénario n'est pas couvert par les documents auxquels vous vous référez.

Pour le deuxième scénario, tout fonctionne parfaitement en termes de fonctionnalité. Tout fonctionne sans aucun problème sur Android. Le seul problème est que sur IOS, seule la classe css correcte n'est pas appliquée à la page poussée lorsqu'elle est poussée à partir d'une superposition. Il existe un correctif CSS simple pour cela.

Collez simplement le suivi dans votre app.scss et vous êtes prêt à partir car la classe correcte sera désormais appliquée aux pages, qu'elles soient poussées à partir d'une page modale ou d'une autre page normale.

Maintenant, les deux scénarios fonctionnent bien.
1) lorsque vous souhaitez supprimer la superposition et charger une nouvelle page, utilisez la méthode dans la documentation de navcontroller.
2) lorsque vous ne voulez pas rejeter la superposition et charger une nouvelle page qui peut revenir en arrière et avoir toujours la superposition source disponible, incluez simplement le css ci-dessous et cela résout le problème de mise en page.

// handle top padding disappearing in modals
<strong i="12">@media</strong> only screen and (max-width: 767px){
    .ios > .ion-page > ion-header > .toolbar.statusbar-padding:first-child {
        padding-top: calc(20px + 4px);
        padding-top: calc(constant(safe-area-inset-top) + 4px);
        padding-top: calc(env(safe-area-inset-top) + 4px);
        min-height: calc(44px + 20px);
        min-height: calc(44px + constant(safe-area-inset-top));
        min-height: calc(44px + env(safe-area-inset-top));
        }
}

@ghenry22 Je pense que tu te trompes. J'utilise la solution recommandée dans une application Ionic et le modal n'est pas rejeté. Il pousse une nouvelle page sur la pile modale, et lorsque l'utilisateur appuie sur "Retour", il revient au modal.

Je pense que votre application a probablement une sorte de bogue si vous ne voyez pas ce comportement avec la solution recommandée. Si j'étais vous, j'ouvrirais une question StackOverflow pour essayer de la déboguer. Quelqu'un là-bas pourrait vous aider à le découvrir.

Ce problème n'est pas au bon endroit, car cette fonctionnalité est déjà dans Ionic et a été suffisamment documentée pour une utilisation générale.

@zmbc https://ionicframework.com/docs/api/navigation/NavController/
Les documents ici pour naviguer à partir d'une superposition montrent que dismiss() est appelé avant de passer à la page suivante. C'est à cela que je faisais allusion.

En fouillant dans les anciens journaux PR, il semble que les mises à jour ajoutées par @wbhob ne soient pas reflétées sur les pages de documentation des composants ioniques. Je vais essayer la solution des anciens commits, mais si cela fonctionne comme vous le dites, il serait bon d'inclure ces informations dans la documentation ou les exemples de l'API du contrôleur de navigation afin qu'elles puissent être trouvées facilement.

Néanmoins, si les classes CSS correctes sont appliquées (comme sur Android), aucune solution de contournement ou code supplémentaire de la part de l'utilisateur n'est nécessaire, ce serait certainement un résultat souhaitable ?

@ghenry22 Je ne sais plus où réside la documentation dans le projet, mais je pense que vous avez raison de dire que les modifications de ModalController , pas NavController ).

Comme je l'ai déjà expliqué , il n'est tout simplement pas vrai que le correctif CSS soit aussi bon que la solution recommandée. Il n'est équivalent que sur les petits écrans où les modaux sont en plein écran, et qui sait si cela fonctionnera dans la prochaine version d'Ionic ? La solution recommandée crée une véritable pile de navigation, ce que vous voulez dans cette situation, fonctionne sur toutes les tailles d'écran et utilise une API publique documentée. Ce n'est pas non plus une grande différence dans la complexité du code : je préférerais de loin avoir quelques lignes de plus de passe-partout qu'un obscur SCSS que je ne pourrai pas comprendre à l'avenir.

Je vous recommande d' utiliser cette approche pour faire exactement ce que vous voulez : pousser une page sur un modal et avoir la possibilité de revenir au modal. Si vous ne voulez pas le faire, c'est à vous de décider. Mais ce n'est clairement pas un problème avec Ionic.

@zmbc la documentation serait sur le navController car c'est ce qui est utilisé pour la navigation. Le ModalControl crée et présente simplement le modal.

Je ne suis pas d'accord pour dire que le CSS est obscur, c'est le CSS ionique standard qui est appliqué à une page lorsqu'il est poussé normalement, je suis d'accord qu'il pourrait cesser de fonctionner ou causer des problèmes s'il y a un changement majeur vers ionic (comme avec la V4 à venir ), c'est pourquoi cela devrait être corrigé en tant que bogue qui affecte la plate-forme iOS pour Ionic afin que les gens n'aient PAS BESOIN d'appliquer un correctif.

Ce problème n'existe pas sur Android, qui fonctionne parfaitement sans aucun changement. Cela semble donc être un bogue spécifique à la plate-forme avec l'application de classes CSS ioniques.

J'admets que je ne l'ai pas encore testé sur un appareil à écran plus grand et qu'il y a peut-être autre chose nécessaire, je vais regarder ça.

Je peux voir qu'il existe une solution qui a été perdue dans la documentation et qui n'existe plus que sous forme de commentaire dans l'en-tête d'un fichier source. Si cette solution peut être restaurée dans la documentation officielle du contrôleur de navigation, dans la section sur la navigation à partir d'un modal, il existe au moins une solution documentée et la documentation est facilement accessible aux personnes lisant la documentation Ionic.

Nous n'allons clairement pas nous mettre d'accord sur l'approche qui est bonne ou mauvaise, donc mettez cela de côté, tant qu'il existe un moyen officiellement recommandé de le faire (quel qu'il soit) correctement ajouté à la documentation, alors c'est assez bon pour moi.

Merci pour le problème ! Ce problème est verrouillé pour empêcher les commentaires qui ne sont pas pertinents pour le problème d'origine. Si le problème persiste avec la dernière version d'Ionic, veuillez créer un nouveau problème et vous assurer que le modèle est entièrement rempli.

Cette page vous a été utile?
0 / 5 - 0 notes