Ionic-framework: Sin relleno para la barra de estado (en iOS) al presionar la navegación dentro de un modal

Creado en 21 sept. 2016  ·  45Comentarios  ·  Fuente: ionic-team/ionic-framework

Breve descripción del problema:

La barra de navegación puede superponerse a la barra de estado en iOS, cuando se empuja una nueva página usando NavController#push desde el interior de un modal. Ver captura de pantalla.

img_2079

¿Qué comportamiento esperas?

Como todas las demás barras de navegación, esta debería dejar suficiente espacio para la barra de estado.

Pasos para reproducir:

  1. Abra un modal.
  2. Dentro del modal, llame a NavController#push con cualquier página.

¿Qué versión iónica? 2

Repo que muestra un ejemplo de su problema

https://github.com/zmbc/statusbar

Vaya a la lista, abra un elemento y luego presione "Empujar algo".

Ejecute ionic info desde el indicador de terminal / cmd: (pegue la salida a continuación)
Versión de Gulp: CLI versión 3.9.1
Gulp local: versión local 3.9.1
Versión de Ionic Framework: 2.0.0-beta.11
Versión Ionic CLI: 2.0.0-beta.32
Versión de Ionic App Lib: 2.0.0-beta.18
ios-deploy versión: 1.8.6
versión ios-sim: 3.1.1
Sistema operativo: Mac OS X El Capitan
Versión de nodo: v6.3.0
Versión de Xcode: Xcode 7.3.1 Versión de compilación 7D1014

Comentario más útil

Todavía presente en 3.3.0 iónico-angular. Alguna manera de arreglarlo?

Todos 45 comentarios

mismo problema aquí. Lo resolví no presionando la nueva página sino presentándola como un segundo modal.

¡Hola a todos! ¡Gracias por usar Ionic !. Me complace informar que ya no puedo reproducir este problema con RC0. ¡Gracias!

Este error todavía existe. Este problema solo se puede reproducir en un dispositivo / emulador real. No aparecerá en los navegadores de escritorio a menos que pase {statusbarPadding: true} a la variable de configuración de IonicModule.forRoot(MyApp, config) . Creé un repositorio rápido para demostrar este problema con RC0 https://github.com/msalcala11/modal-padding-bug.

El mismo problema aquí.

También puede confirmar este problema

sí, este problema todavía existe. por favor reabrir

Tenemos que documentar mejor los modales, tenemos gente trabajando en esto ahora mismo.
@comfortme @royipressburger @CyrisXD @ msalcala11 @zmbc Tienes que crear un nuevo ion-nav para tener navegación dentro de un modal, al igual que lo haces para tener navegación en tu aplicación.

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

esto todavía no tiene sentido para mí.

Tengo una página a la que navegaré desde otra página O desde un modal dependiendo de dónde se encuentre el usuario en la aplicación.

Cuando hago un nav.push dentro del modal, va a la página, todo cambia bien y funciona exactamente como quiero. EXCEPTO que el relleno de la barra de estado no se aplica cuando navego a la página desde un modal.

Realmente no veo cómo el fragmento de código anterior me ayuda con eso. Esto parece que debería ser algo realmente simple, ya que funcionalmente todo está funcionando Y en una de las versiones beta anteriores, el relleno de la barra de estado también se aplicó correctamente, pero esto se rompió nuevamente en una versión posterior.

Tenga en cuenta que Android no tiene ningún problema con el mismo código, la navegación desde otra página o desde un modal, todo está formateado correctamente y funciona bien, esperaría que ios sea el mismo.

Todavía existe. ¿Algún truco simple para evitar esto?

Aplique el siguiente CSS a ion-navbar y ion-title para solucionar este problema. Utilizo un ngIf * para aplicarlo solo si el platform.is (iOS) ya que Android no lo necesita. Esto simplemente es anulado por el CSS predeterminado cuando se abre desde otra página en iOS, por lo que tampoco hay problemas.

También tenga en cuenta que cualquier alerta / hoja de acción / ventana emergente que abra desde la página recién enviada se abrirá detrás de la página. Deberá piratear el valor del índice z para que esos componentes sean más altos que el índice z modal para que siempre estén en la parte superior. Dado que esas cosas siempre deberían estar en la parte superior de todos modos, eso no es realmente un problema.

<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>

Todavía tengo este problema. ¿Se solucionará esto pronto?

@mrhirsch Hay un problema similar aquí . Echale un vistazo. No está arreglado, pero @manucorporat pidió un ejemplo de repositorio que proporcioné allí, así que espero que estén trabajando en ello.

@ ghenry22

La forma en que está haciendo ese relleno no es una buena manera. No use *ngIf para ocultar las barras de navegación según los tipos de plataforma. El cálculo del ion-content posteriormente no tendrá en cuenta la barra de navegación y hará que todo el ion-content mueva hacia arriba.

En su lugar, en app.scss , agregue el siguiente CSS.

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

Luego, simplemente en el encabezado que necesita esto (para mí, son todas las páginas donde presiono la página de pestaña), simplemente agregue class="ios-header" .

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

Mucho más SECO, y sin el problema de ion-content . Por supuesto, si el Equipo Iónico investigara esto por sí mismo, no tendríamos que pasar por este dolor.

Para cualquiera que se tropiece con esto con un popover, este es el mismo problema.

Con respecto a la solución: no es una buena idea optar por el enfoque de corrección de CSS porque solo está enmascarando algo que no está haciendo según lo diseñado (incluso si es un diseño un poco extraño tbh).

Otra solución distinta a la que señala manucorporat es trabajar con eventos. Lo hice así y es muy sencillo y limpio. Simplemente dispara un evento en tu página modal o popover y escúchalo en tu página "parrent". Puede encontrar más información sobre los eventos aquí: https://ionicframework.com/docs/api/util/Events/

@timvandijck ¿Puede

@ kabus202 este es un ejemplo con un popover:

La página donde está iniciando el 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 página que contiene el contenido del 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');
    }
}

Sí, esto sigue siendo un problema. Además, cuando intenta deslizar el dedo para volver atrás, a veces puede actuar y hacer aparecer la vista debajo del modal. @ jgw96

Todavía presente en 3.3.0 iónico-angular. Alguna manera de arreglarlo?

@manucorporat ¿Podría volver a abrir este problema? Abrir modal en la página abierta por navController.push () causa la misma situación que se muestra en la primera publicación.

Sí, por favor vuelva a abrir

@vosecek El problema existe, pero puede usar mi corrección de CSS que publiqué anteriormente. Funciona con 3.3.

Hola chicos, eche un vistazo a la API de NavController , específicamente la sección titulada Navegación desde un componente de superposición (pegado a continuación)

Tenga en cuenta el uso de this.appCtrl.getRootNav() . Esto funcionó muy bien para mí, así que tengo curiosidad por saber si el uso de App soluciona este problema para otros. De todos modos, pensé que todos deberían saber sobre esto.

Navegación desde un componente de superposición

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

Supongo que la pregunta es ¿por qué agregarías tanta sobrecarga cuando solo puedes nav.push y todo funciona completamente bien, excepto un poco de CSS que nadie parece interesado en arreglar?

Me recuerda un poco a la respuesta de Apple "simplemente manténgalo diferente" a los problemas de la antena.

¿Por qué este tema está cerrado si todavía está ahí?

@edwinchoate esto funciona, pero no cuando todavía necesita que el popover esté activo cuando regresa de la página. No creo que sea posible navegar fuera y volver a una ventana emergente como una página normal con el diseño actual, la ventana emergente está ubicada en una capa más alta que todas las páginas normales, por lo que es necesario descartarla. A menos que cambien el comportamiento de popover por completo.

Dado que este error no se ha solucionado, agregué este código SCSS como solución alternativa y funcionó para mí. Espero que te sea de utilidad:

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

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

A toda la gente que todavía tropieza con esto. @manucorporat ya presentó la idea correcta. El código solo tiene un error y está algo incompleto. He probado esto con Ionic 3.6.0 .

En la página de contenido que presenta como modal, simplemente incluya otra clase de página contenedora con un elemento de navegación como este:

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

Y luego modifique la clase de su página de contenido de esta manera:

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

Ahora puede llamar a closeModal como una función normal en su clase o plantilla.

Ahora todo lo que queda por hacer es reemplazar MyModalContentPage con MyModalWrapper dondequiera que cree y presente el modal. Entonces en lugar de:

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

hacer esto:

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

Espero que esto ayude.

@codemusings lo hice de esta manera:

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

Al pasar el ViewController completo, puede usar el mismo this.viewCtrl.dismiss() que usaría normalmente; no son necesarios cambios en la página de contenido excepto en el constructor.

Estoy en Ionic 3.3.0 pero supongo que también funcionaría en la última versión.

Pero la cuestión es que, funcionalmente, funciona completamente bien tal como está y no hay necesidad de todo ese código adicional, solo una corrección de CSS de una sola línea solo para iOS y esto ni siquiera es un problema.

@ ghenry22 Eso no es del todo correcto para pantallas grandes, por ejemplo, iPad, donde la página enviada es a pantalla completa aunque el modal es pequeño.

Deseo nav.push dentro de un modal Just Worked. Pero prefiero hacerlo de esta manera más compleja que confiar en correcciones de CSS más pirateadas.

@ ghenry22 @zmbc La vista de navegación implica una pila de navegación separada, que usted crea al abrir un modal. Esta es la forma".

Cuando llamas a navCtrl.pop, puede crear problemas inadvertidos con la navegación raíz, ya que Ionic no entiende cuándo estás en un modal y cuándo no.

¿Tampoco tengo ningún problema con las páginas enviadas en iOS? Quiero decir, lo probaré de nuevo ahora que lo mencionaste para asegurarme, pero se mantienen dentro de los límites del modal para mí.

Básicamente, si presiono o abro una página desde dentro de un modal, espero que se cargue y se vincule dentro del modal.

Si presiono o aparezco en una página normal, espero que se cargue con la página normal de pantalla completa.

Tengo páginas que puedo usar en cualquier escenario, por lo que agregar código para manejar un escenario puede causar problemas en el otro.

Si desea que la página presionada dentro de un modal se abra en pantalla completa en el ipad, supongo que tendría que tener una función que cierre el modal y luego presione la página, lo que seguramente podría complicarse un poco.

@wbhob, este puede ser el resultado deseado, pero todo lo que tiene que hacer es mirar este ticket y los foros iónicos y el desbordamiento de la pila para ver la misma pregunta una y otra vez.

Entonces, obviamente, es un problema desde el punto de vista de la usabilidad pura para las personas. Sería genial si ionic pudiera implementar algo bajo el capó para que "simplemente funcionara", entonces todos los comentarios y solicitudes sobre este problema cerrado se detendrían :)

Hizo un PR para los docs @ ghenry22

¡Mi PR se fusionó! Consulta los documentos modales

@ jgw96 Espero que esto se resuelva con Ionic4. Ha sido sobresaliente desde ionic2 RC0 sin acción, lo cual es un poco impactante considerando que es una simple corrección de CSS y luego el uso de la navegación funciona como se esperaba, ya sea que esté en una página modal o normal. Como debería.

Funciona como se esperaba, no es un problema. Hay detalles sobre cómo hacer esto en los documentos de Ionic (escribí esa parte de los documentos)

@wbhob excepto que no funciona como se esperaba. Como se muestra en los numerosos hilos del foro. Problemas aquí y en el desbordamiento de la pila.

La navegación funciona exactamente como cabría esperar, con la excepción de que la página enviada pierde su estado en el relleno. Esta es una solución css simple y no requiere nada más complicado.

Su solución recomendada y otras implican cerrar la superposición antes de abrir la nueva página. Este no es un enfoque factible para mi aplicación, ya que quiero que el usuario pueda ver cierta información desde un modal O desde otras páginas regulares y, si lo ve desde un modal, quiero que puedan volver al modal.

De todos modos, publiqué una solución css solo para esto en uno de los otros problemas registrados para esto el otro día que lo resolvió por completo simplemente aplicando los estilos de página iónicos estándar, ya que estarían en una configuración no modal.

La forma correcta de hacer esto es crear una instancia de navegación autónoma dentro del modal. Su intención es navegar a páginas adicionales, pero cuando llama a navCtrl.push, como era de esperar, lo ejecuta contra la pila de navegación raíz, ya que no conoce nada mejor. Cuando lo hace correctamente y crea una pila de navegación exclusiva del modal, funciona correctamente.

Sí, esa es una forma de hacerlo para un escenario específico. Suponiendo que en su caso de uso desea descartar la superposición que está abierta (modal / pop over, etc.) y ENTONCES abra la página. En este escenario, sí, lo que ha dicho y lo que se muestra en los documentos del componente Ionic para el controlador de navegación funciona bien.

No quiero descartar el modal que está abierto, quiero poder navegar a una página que mostrará información adicional, y cuando termine, haga clic en ATRÁS para volver al modal desde donde se abrió la página. Este escenario no está cubierto por los documentos a los que hace referencia.

Para el segundo escenario, todo funciona perfectamente en términos de funcionalidad. Todo funciona sin problemas en Android. El único problema es que en IOS solo la clase CSS correcta no se aplica a la página enviada cuando se envía desde una superposición. Hay una solución de CSS simple para esto.

Simplemente inserte el seguimiento en su app.scss y estará listo, ya que ahora se aplicará la clase correcta a las páginas, ya sea que se envíen desde una página modal u otra normal.

Ahora ambos escenarios funcionan bien.
1) cuando desee descartar la superposición y cargar una nueva página, use el método en los documentos de navcontroller.
2) cuando no desee descartar la superposición y cargar una nueva página que puede retroceder y aún tener la superposición de origen disponible, simplemente incluya el CSS a continuación y resuelve el problema de diseño.

// 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 Creo que estás equivocado. Estoy usando la solución recomendada en una aplicación iónica y el modal no se descarta. Empuja una nueva página en la pila modal, y cuando el usuario toca "Atrás", regresa al modal.

Creo que su aplicación probablemente tenga algún tipo de error si no está viendo ese comportamiento con la solución recomendada. Si fuera usted, abriría una pregunta de StackOverflow para intentar depurarla. Alguien allí podría ayudarte a resolverlo.

Este problema no es el lugar correcto, porque esta funcionalidad ya está en Ionic y se ha documentado adecuadamente para uso general.

@zmbc https://ionicframework.com/docs/api/navigation/NavController/
Los documentos que se muestran aquí para navegar desde una superposición muestran que se llama a despedir () antes de navegar a la página siguiente. A esto me refería.

Examinando los antiguos registros de relaciones públicas, parece que las actualizaciones agregadas por @wbhob no se reflejan en las páginas de documentación del componente iónico. Probaré la solución de las confirmaciones anteriores, pero si funciona como dice, sería bueno que esa información se incluyera en los documentos o ejemplos de la API del componente del controlador de navegación para que se pueda encontrar fácilmente.

Aún así, si se aplican las clases CSS correctas (como en Android), entonces no hay necesidad de ninguna solución o código adicional por parte del usuario, seguramente este sería un resultado deseable.

@ ghenry22 Ya no estoy seguro de dónde reside la documentación en el proyecto, pero creo que tienes razón en que los cambios de @wbhob ya no están allí (aunque estarían en ModalController , no en NavController ).

Como expliqué antes , simplemente no es cierto que la corrección de CSS sea tan buena como la solución recomendada. Solo es equivalente en pantallas pequeñas donde los modales son de pantalla completa, y ¿quién sabe si funcionará en la próxima versión de Ionic? La solución recomendada crea una verdadera pila de navegación, que es lo que desea en esta situación, funciona en todos los tamaños de pantalla y utiliza una API pública documentada. Tampoco es una gran diferencia en la complejidad del código: preferiría tener algunas líneas más de texto estándar que un SCSS oscuro que no podré entender en el futuro.

Te recomiendo que uses este enfoque para hacer exactamente lo que quieres: empujar una página en un modal y tener la capacidad de volver al modal. Si no quiere hacer eso, depende de usted. Pero esto claramente no es un problema con Ionic.

@zmbc, la documentación estaría en navController ya que eso es lo que se usa para la navegación. ModalControl simplemente crea y presenta el modal.

No estoy de acuerdo con que el CSS sea oscuro, es el CSS iónico estándar que se aplica a una página cuando se presiona normalmente, estoy de acuerdo en que podría dejar de funcionar o causar problemas si hay un cambio importante en iónico (como con la próxima versión de V4 ) por lo que esto debería corregirse como un error que afecta a la plataforma iOS para Ionic para que la gente no NECESITA aplicar ninguna corrección.

Este problema no existe en Android, que funciona perfectamente sin cambios. Entonces, esto parece ser un error específico de la plataforma con clases de CSS de aplicación iónica.

Admito que aún no lo he probado en un dispositivo de pantalla más grande y es posible que se necesite algo más allí, lo veré.

Puedo ver que hay una solución que se ha perdido de los documentos y ahora existe solo como un comentario en el encabezado de un archivo fuente. Si esta solución se puede restaurar a los documentos oficiales del controlador de navegación, en la sección sobre cómo navegar desde un modal, entonces al menos hay una solución que está documentada y la documentación es fácilmente accesible para las personas que leen los documentos Ionic.

Claramente no vamos a ponernos de acuerdo sobre qué enfoque es correcto o incorrecto, así que dejando eso a un lado, siempre que haya una forma oficialmente recomendada de hacer esto (sea lo que sea) agregada correctamente a los documentos, entonces eso es lo suficientemente bueno para mí.

¡Gracias por el problema! Este problema se está bloqueando para evitar comentarios que no sean relevantes para el problema original. Si esto sigue siendo un problema con la última versión de Ionic, cree un nuevo problema y asegúrese de que la plantilla esté completa.

¿Fue útil esta página
0 / 5 - 0 calificaciones