Ionic-framework: 在模态内进行导航推送时,状态栏没有填充(在 iOS 上)

创建于 2016-09-21  ·  45评论  ·  资料来源: ionic-team/ionic-framework

问题的简短描述:

当使用NavController#push从模态内部推送新页面时,导航栏可以与 iOS 上的状态栏重叠。 见截图。

img_2079

你期待什么行为?

像所有其他导航栏一样,这个导航栏应该为状态栏留出足够的空间。

重现步骤:

  1. 打开一个模态。
  2. 在模态中,对任何页面调用NavController#push

哪个离子版本? 2

显示您的问题示例的回购

https://github.com/zmbc/statusbar

转到列表,打开一个项目,然后点击“推送某物”。

从终端/cmd 提示符运行ionic info :(在下面粘贴输出)
Gulp 版本:CLI 版本 3.9.1
Gulp 本地:本地版本 3.9.1
离子框架版本:2.0.0-beta.11
离子 CLI 版本:2.0.0-beta.32
离子应用程序库版本:2.0.0-beta.18
ios 部署版本:1.8.6
ios-sim 版本:3.1.1
操作系统:Mac OS X El Capitan
节点版本:v6.3.0
Xcode 版本:Xcode 7.3.1 构建版本 7D1014

最有用的评论

仍然存在于 ionic-angular 3.3.0 中。 有什么办法可以解决吗?

所有45条评论

同样的问题在这里。 我通过不推送新页面而是将其呈现为第二个模式来解决它。

大家好! 感谢您使用 Ionic!。 我很高兴地报告,我无法再使用 RC0 重现此问题。 谢谢!

这个bug依然存在。 此问题只能在实际设备/模拟器上重现。 它不会出现在桌面浏览器上,除非您将 { statusbarPadding: true } 传递给IonicModule.forRoot(MyApp, config)的配置变量。 我创建了一个快速存储库来演示这个问题与 RC0 https://github.com/msalcala11/modal-padding-bug。

同样的问题在这里。

也可以确认这个问题

是的,这个问题仍然存在。 请重新打开

我们必须更好地记录模态,我们现在有人在做这方面的工作。
@comfortme @royipressburger @CyrisXD @msalcala11 @zmbc您必须创建一个新的 ion-nav 才能在模态内进行导航,就像在应用程序中进行导航一样。

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

这对我来说仍然没有意义。

我有一个页面,我将根据用户在应用程序中的位置从另一个页面或从模式导航到该页面。

当我在模态中执行 nav.push 时,它会转到页面,一切都很好地过渡并且完全按照我的意愿工作。 除了当我从模式导航到页面时不会应用状态栏填充。

我真的不明白上面的代码片段是如何帮助我做到这一点的? 这似乎应该是一件非常简单的事情,因为功能上一切正常,并且在早期的测试版之一中,状态栏填充也被正确应用,但在以后的版本中又被破坏了。

请注意,android 对相同代码没有任何问题,无论是从另一个页面还是从模式导航,所有格式都正确且工作正常,我希望 ios 是相同的。

仍然存在。 有什么简单的技巧可以防止这种情况发生?

将以下 CSS 应用于 ion-navbar 和 ion-title 以解决此问题。 我使用 ngIf* 仅在 platform.is(iOS) 作为 android 不需要它时才应用它。 从 iOS 上的另一个页面打开时,这只是被默认 css 覆盖,因此也没有问题。

另请注意,您从新推送的页面打开的任何警报/操作表/弹出窗口都将在页面后面打开。 您需要修改这些组件的 z-index 值,使其高于模态 z-index,以便它们始终位于顶部。 考虑到这些东西应该总是在上面,这不是一个真正的问题。

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

还是有这个问题。 这会很快解决吗?

@mrhirsch有一个类似的问题在这里。 一探究竟。 它不是固定的,但@manucorporat要求提供我在那里提供的 repo 示例,因此希望他们正在努力。

@ghenry22

你做填充的方式不是一个好方法。 不要使用*ngIf来隐藏基于平台类型的导航栏。 随后ion-content的计算将不考虑导航栏,并将导致整个ion-content上移。

相反,在app.scss ,添加以下 CSS。

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

然后只需在您需要这个的标题中(对我来说,这是我推到 Tab 页面的所有页面),只需添加class="ios-header"

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

很多 DRYer,而且没有ion-content问题。 当然,如果 Ionic 团队自己研究这个问题,我们就不必经历这种痛苦。

对于任何通过弹出窗口绊倒这个的人来说,这是同样的问题。

关于解决方案:采用 CSS 修复方法不是一个好主意,因为您只是掩盖了您没有按照设计做的事情(即使它有点奇怪的设计 tbh)。

除了 manucorporat 所指出的,另一种解决方案是使用事件。 我就是这样做的,它非常简单和干净。 只需在您的模态或弹出页面中触发一个事件并在您的“父”页面中监听它。 可以在此处找到有关事件的更多信息: https :

@timvandijck你能举个例子吗?

@kabus202这是一个带有弹出

您启动弹出窗口的页面:

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

包含弹出框内容的页面:

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

    constructor(public events: Events) {
    }

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

是的,这仍然是一个问题。 此外,当您尝试滑动返回时,它有时会起作用并弹出模态下的视图。 @jgw96

仍然存在于 ionic-angular 3.3.0 中。 有什么办法可以解决吗?

@manucorporat你能重新打开这个问题吗? 在由 navController.push() 打开的页面中打开模态会导致与第一篇文章中的图片相同的情况。

是的,请重新打开

@vosecek问题存在,但您可以使用我在上面发布的 css 修复程序。 它适用于 3.3。

嘿伙计们,查看NavController api ,特别是标题为Navigating from an Overlay Component 的部分(粘贴在下面)

注意this.appCtrl.getRootNav() 。 这对我来说效果很好,所以我很好奇使用App是否可以为其他人解决这个问题。 无论如何,只是想你们都应该知道这一点。

从叠加组件导航

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

我想问题是当你可以只使用 nav.push 并且一切正常,除了一些似乎没有人有兴趣修复的 CSS 之外,你为什么要添加这么多东西?

这让我想起了苹果对天线问题的“只是保持不同”的反应。

如果这个问题仍然存在,为什么它会被关闭?

@edwinchoate这有效,但当您从页面返回时仍然需要弹出窗口处于活动状态时则无效。 我认为不可能像使用当前设计的普通页面那样导航并返回弹出框,弹出框位于比所有普通页面更高的层上,因此需要关闭。 除非他们完全改变 popover 的行为。

由于此错误尚未修复,因此我添加了此 SCSS 代码作为解决方法,它对我有用。 我希望它对你有用:

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

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

致所有仍在为此而绊倒的人。 @manucorporat已经提出了正确的想法。 代码只是有一个错误,有点不完整。 我已经用 Ionic 3.6.0对此进行了测试。

在您作为模态呈现的内容页面中,只需包含另一个带有导航元素的包装页面类,如下所示:

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

然后像这样修改您的内容页面类:

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

现在您可以像在类或模板中调用普通函数一样调用closeModal

现在剩下要做的就是将MyModalContentPage替换MyModalWrapper在您创建和显示模态的任何地方。 所以而不是:

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

做这个:

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

希望这可以帮助。

@codemusings我是这样做的:

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

通过传入整个ViewController您可以使用通常使用的相同的this.viewCtrl.dismiss() ; 除了构造函数之外,不需要对内容页面进行任何更改。

我在 Ionic 3.3.0但我猜它也适用于最新的。

但问题是,在功能上它完全正常工作,不需要所有额外的代码,只需要针对 iOS 的单行 CSS 修复,这甚至不是问题。

@ghenry22这对于大屏幕并不完全正确,例如 iPad,即使模态很小,推送的页面也是全屏的。

我希望nav.push在模态 Just Worked 中。 但我宁愿用这种更复杂的方式来完成它,也不愿依赖 hackier CSS 修复。

@ghenry22 @zmbc导航视图意味着一个单独的导航堆栈,您在打开模态时创建它。 这就是“道”。

当您调用 navCtrl.pop 时,它可能会无意中创建根导航的问题,因为 Ionic 不知道您何时处于模态中,何时不在。

我对 iOS 上的推送页面也没有任何问题? 我的意思是,既然您已经提到了它,我将再次对其进行测试,以确保它们对我来说保持在模态的范围内。

基本上,如果我从模态中推送或弹出页面,我希望它加载并绑定在模态中。

如果我在普通页面上推送或弹出我希望它以普通全屏页面加载。

我有可以在任何一种情况下使用的页面,因此添加代码来处理一种情况可能会导致另一种情况出现问题。

如果您希望模态内的推送页面在 ipad 上全屏打开,那么我猜您必须具有关闭模态然后推送页面的功能,这肯定会变得有点混乱。

@wbhob这可能是你想要的结果,但你所要做的就是查看这张票、离子论坛和堆栈溢出,看看一遍又一遍地问同样的问题。

所以很明显,从人们纯粹的可用性角度来看,这是一个问题。 如果 ionic 可以在幕后实现一些东西,以便它“正常工作”,那么关于这个已关闭问题的所有评论和请求都将停止,那就太好了:)

对文档@ghenry22做了 PR

我的pr被合并了! 检查模态文档

@jgw96我希望

它按预期工作,这不是问题。 Ionic 文档中有关于执行此操作的详细信息(我写了文档的那部分)

@wbhob除非它没有按预期工作。 正如论坛上的众多主题所示。 这里和堆栈溢出的问题。

导航与您期望的完全一样,除了推送的页面在填充时失去其状态。 这是一个简单的 css 修复,不需要任何更复杂的东西。

您推荐的解决方法和其他方法涉及在打开新页面之前关闭覆盖层。 这对我的应用程序来说不是一种可行的方法,因为我希望用户能够从模态或其他常规页面查看一些信息,如果从模态查看,我希望他们能够返回到模态。

无论如何,我在前几天为此记录的其他问题中发布了一个 css only fix,它通过简单地应用标准离子页面样式为我完全解决了它,就像它们在非模态设置中一样。

这样做的正确方法是在模态内部创建一个自包含的导航实例。 您的意图是导航到其他页面,但是当您调用 navCtrl.push 它时,正如您所期望的那样,它会针对根导航堆栈运行它,因为它不知道更好。 当您正确执行此操作并使导航堆栈专用于模态时,它会正常运行。

是的,这是针对特定场景的一种方式。 假设在您的用例中,您想要关闭打开的叠加层(模态/弹出等),然后打开页面。 在这种情况下,是的,您所说的以及导航控制器的 Ionic 组件文档中显示的内容都可以正常工作。

我不想关闭打开的模式,我希望能够导航到一个将显示一些附加信息的页面,完成后单击 BACK 返回到打开页面的模式。 您参考的文档未涵盖此场景。

对于第二种情况,就功能而言,一切都完美无缺。 在 Android 上一切都没有问题。 唯一的问题是,在 IOS 上,当从叠加层推送页面时,只有正确的 css 类不会应用于推送页面。 对此有一个简单的 CSS 修复。

只需将以下内容粘贴到您的 app.scss 中,您就一切顺利了,因为正确的类现在将应用于页面,无论它们是从模态页面还是其他常规页面推送。

现在这两种情况都运行良好。
1) 当您想关闭覆盖层并加载新页面时,请使用 navcontroller 文档中的方法。
2)当您不想关闭覆盖并加载一个可以返回并仍然可以使用源覆盖的新页面时,只需包含下面的css即可解决布局问题。

// 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我认为你错了。 我在 Ionic 应用程序中使用推荐的解决方案,并且没有取消模态。 它将新页面推送到模态堆栈上,当用户点击“返回”时,他们返回到模态。

如果您在推荐的解决方案中没有看到该行为,我认为您的应用程序可能存在某种错误。 如果我是你,我会打开一个 StackOverflow 问题来尝试调试它。 那里有人可以帮助您解决问题。

这个问题不是正确的地方,因为这个功能已经在 Ionic 中并且已经被充分记录以供一般使用。

@zmbc https://ionicframework.com/docs/api/navigation/NavController/
此处用于从叠加层导航的文档显示在导航到下一页之前调用了dismiss()。 这就是我所指的。

翻阅旧的 PR 日志,似乎@wbhob添加的更新没有反映在离子组件文档页面上。 我将尝试旧提交中的解决方案,但如果它如您所说的那样有效,那么将这些信息包含在导航控制器组件 API 文档或示例中会很好,因此实际上可以轻松找到它。

如果应用了正确的 CSS 类(如在 Android 上),则不需要任何解决方法或用户的额外代码,这肯定是一个理想的结果吗?

@ghenry22我不确定文档在项目中的位置,但我认为@wbhob的更改不再存在是正确的(尽管它们将在ModalController 中,而不是NavController )。

正如我之前解释过的,CSS 修复与推荐的解决方案一样好是不正确的。 它只在模态全屏的小屏幕上等效,谁知道它是否可以在下一版本的 Ionic 中工作? 推荐的解决方案创建一个真正的导航堆栈,这是您在这种情况下想要的,适用于所有屏幕尺寸,并使用文档化的公共 API。 这在代码复杂性方面也没有太大区别:我宁愿多几行样板,也不愿一些我将来无法理解的晦涩的 SCSS。

我建议您使用这种方法来做您想做的事情:在模态上推送页面并能够返回到模态。 如果你不想这样做,那取决于你。 但这显然不是 Ionic 的问题。

@zmbc文档将在 navController 上,因为它用于导航。 ModalControl 仅创建和呈现模态。

我不同意 CSS 晦涩难懂,它是在正常推送时应用于页面的标准 ionic CSS,我同意如果 ionic 发生重大变化(例如 V4 即将推出),它可能会停止工作或导致问题) 这就是为什么这应该被修复为影响 Ionic 的 iOS 平台的错误,所以人们不需要应用任何修复。

Android 上不存在此问题,无需任何更改即可完美运行。 所以这似乎是一个平台特定的错误,离子应用 CSS 类。

我承认我还没有在更大屏幕的设备上测试过它,那里可能还需要其他东西,我会看看。

我可以看到有一个解决方案已从文档中丢失,现在仅作为源文件标题中的注释存在。 如果这个解决方案可以恢复到官方的导航控制器文档,进入关于从模态导航的部分,那么至少有一个解决方案被记录在案,并且文档很容易被阅读 Ionic Docs 的人访问。

我们显然不会就哪种方法正确或错误达成一致,所以把它放在一边,只要有官方推荐的方法(无论它是什么)正确添加到文档中,那么这对我来说就足够了。

感谢您的问题! 此问题已被锁定,以防止发表与原始问题无关的评论。 如果使用最新版本的 Ionic 仍然存在问题,请创建一个新问题并确保模板已完整填写。

此页面是否有帮助?
0 / 5 - 0 等级