首页 > 解决方案 > NavigationController 中的视图之间的分隔无法正常工作

问题描述

我有一个应用程序,其中包含一个设置视图,该设置视图是使用带有原型单元的 UITableView 设置的。填充后,每个单元格将引导至后续设置页面。然后,这些后续设置页面应允许用户导航回主设置页面(并最终退出设置返回主菜单)。

每个设置页面的基本机制都独立正常工作。我遇到的问题是将这些都捆绑在一个导航流程中。

第一种方法

最初,我将设置屏幕编码为多个不同的视图控制器,并从主设置屏幕为每个视图控制器创建手动转场(并手动创建转场回到主设置屏幕)。主设置屏幕本质上是一个带有原型单元的可视化自定义 UITableView。这种方法按预期工作,但由于需要在每个屏幕上手动编码每个 segue,因此非常笨拙。

新方法(不起作用)

为了使事情更清洁和更易于管理(代码方面),我尝试使用导航控制器来实现相同的效果,并将我的主要设置页面嵌入到导航控制器中(这可能不是正确的术语,但本质上是主设置页面是您通过导航控制器进入情节提要时看到的)。从那里,我使用 segues 将主设置页面连接到每个辅助设置页面。

使用导航控制器方法,主设置页面正确加载并正常工作(即:正确的内容加载、表格滚动、开关工作等),但每当点击一个单元格时,它应该调用二级设置的 segue页面,似乎什么也没发生……但是我可以看到打印行已针对所选的辅助设置页面运行,而主设置页面只是冻结并变得无法正常工作。

通往下一个主要设置屏幕的简单演示:https ://imgur.com/qnzb36j.png

Segue 标识符和详细信息: https ://imgur.com/W3Gn7WS.png

以下代码在主设置屏幕中用于启动到 Timer 屏幕的 segue(例如)。Timer 屏幕的 segue 具有标识符“ShowTimerView”。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)

        print("\(indexPath.row) was selected.")

        if indexPath.row == 1 {
            // Action when timer button pressed
            print("Timer button pressed.")
            print("-----Segueing to Timer view.")
            self.performSegue(withIdentifier: "ShowTimerView", sender: nil)
        }
}

如前所述,点击计时器单元格以导航到计时器屏幕会导致主设置屏幕变得无响应,并且计时器屏幕永远不会出现。我可以告诉计时器屏幕已加载/运行为计时器页面的 ViewController 运行中的打印行并出现在终端中。

我试过玩各种不同的东西来让它工作。我认为我正在犯一个愚蠢的错误,因为当我将 segue 类型从“显示”更改为“模态显示”时,计时器屏幕会加载并出现......但导航栏没有加载所以没有办法导航回主设置屏幕。

作为一个仅供参考,当我从主菜单导航到主设置屏幕时,我确实得到了以下终端输出......不确定它是否有助于解决这个问题:

Settings button pressed.
-----Segueing to Settings view.
2019-01-20 20:54:58.979042+0000 ThirtySeconds[14618:388866] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x600001f68690 UILabel:0x7fb2a1d636b0'Settings'.top >= UILayoutGuide:0x600000560fc0'TitleView(0x7fb2a1c62740)'.top   (active)>",
    "<NSLayoutConstraint:0x600001f685a0 UILabel:0x7fb2a1d636b0'Settings'.firstBaseline == UILayoutGuide:0x600000560fc0'TitleView(0x7fb2a1c62740)'.top + 28   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600001f68690 UILabel:0x7fb2a1d636b0'Settings'.top >= UILayoutGuide:0x600000560fc0'TitleView(0x7fb2a1c62740)'.top   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

然后一旦我按下 Timer 单元格,就会出现以下输出:

Timer button pressed.
-----Segueing to Timer view.
2019-01-20 20:55:38.339771+0000 ThirtySeconds[14618:388866] [Answers] Logging Answers event: <ANSPredefinedEvent: content_view
{
    "content_id" = "N/A";
    "content_name" = Timer;
    "content_type" = "Settings Screen";
}
{
}>
2019-01-20 20:55:38.359086+0000 ThirtySeconds[14618:389499] [Answers] Logging predefined event to Firebase. <select_content
{
    "content_type" = "Settings Screen";
    "item_id" = "N/A";
    "item_name" = Timer;
}>
2019-01-20 20:55:38.365187+0000 ThirtySeconds[14618:388866] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x600001f6ab20 UILabel:0x7fb2a1d73f60'Timer'.top >= UILayoutGuide:0x600000561ce0'TitleView(0x7fb2a1c110a0)'.top   (active)>",
    "<NSLayoutConstraint:0x600001f6a850 UILabel:0x7fb2a1d73f60'Timer'.firstBaseline == UILayoutGuide:0x600000561ce0'TitleView(0x7fb2a1c110a0)'.top + 28   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600001f6ab20 UILabel:0x7fb2a1d73f60'Timer'.top >= UILayoutGuide:0x600000561ce0'TitleView(0x7fb2a1c110a0)'.top   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

标签: iosswiftuinavigationcontrollernavigationuinavigationbar

解决方案


啊! 原来问题是我在子类导航控制器中所做的高度修改。删除此修改会导致一切按预期运行和表现。


推荐阅读