-1

我的问题的高级摘要:

我有一个 UITableViewController (TVC1),它执行 performSegue 来调用静态 UITableViewController (TVC2),以便用户可以输入详细信息。在 TVC2 上按下一个名为“添加另一个”的按钮后,我希望 TVC2 保存其数据并再次调用以添加另一条记录。

细节:

我有一个实现此数据模型的 tableViewController (TVC1):

- Category <=> maps to tableview sections
  - Group <=> maps to tableview rows
    - Detail <=> maps to tableview rows

显示可能如下所示:

- Section 0: Category 1
  - Row 0: Group A
  - Row 1: Detail x1
  - Row 2: Detail y2
  - Row 3: Detail z3
  - Row 4: Group B
  - Row 5: Detail x2
  - Row 6: Detail y2
  - Row 7: Detail y3

例如,当我想通过单击详细信息行 5 来编辑详细信息时,我performSeguedidSelectRowAt.

TVC1.prepareForSegue我提供 TVC1 作为 TVC2 的代表,可以添加/编辑该细节。我还将要编辑的细节数据提供给 TVC2 的属性。

在 TVC2 上 - 提供详细信息后 - 用户可以单击工具栏中的保存按钮,这将保存数据并将他带回 TVC1。或者,在可以输入详细信息的表格末尾,我有一个按钮:

  • 添加另一个细节

这个想法是用户被直接带到一个新屏幕,他们可以在其中为同一组添加另一个详细信息。所以基本上在 TVC2 消失后,它应该会再次出现以添加新的细节。

在 TVC2 中,我将此按钮链接到unwindFromTVC1 上的方法。然后在prepareForSegueTVC2 中,我调用委托 (TVC1) 上的协议方法以返回编辑的详细信息,并提供一个调用结构NextAction来通知根 TVC1 它的下一步应该是什么。在这种情况下,它应该在同一组中添加另一个细节。

然后在unwindFromTVC1 的方法中,我查看nextAction并启动下一个performSegue.

我不知道其他地方可以做到这一点。对我来说,这是我可以展示下一个动作的最后一个钩子,再次是 TVC2。

这会导致奇怪的行为。它似乎工作一次,但不是第二次。

调试显示(=====> 行是我自己的打印调试行):

========> TVC2 prepare start (means the add more details button was pressed)
========> TVC1 newDetailValues begin (TVC2 calling the delegate protocol method to provide back edited data - including NextAction)
========> TVC1 newDetailValues end
========> TVC2 prepare end (I am not sure if TVC2 is now closed/inaccessible)
========> TVC1 unwindFromAddEdit begin (here nextAction is evaluated and a performSegue done)
========> TVC1 prepare begin (initiated by the performSegue)
========> TVC1 prepare end
'Presenting view controllers on detached view controllers is discouraged <Project.TVC1: 0x.........>.'
========> TVC1 unwindFromAddEdit end

注意错误/警告:

'Presenting view controllers on detached view controllers is discouraged <Project.TVC1: 0x.........>.'

但我确实看到了 TVC2 的细节。但是当我再次单击该按钮时,它会显示根 TVC1 而不是 TVC2。xcode 现在说:

'Warning: Attempt to present <UINavigationController: 0x.........> on <Project.TVC1: 0x.........> whose view is not in the window hierarchy!'

我觉得这与线程有关——可能在TVC1.unwindFromTVC2 的范围内运行。

当我编辑TVC1.unwindFrom和替换时:

performSegue(withIdentifier: "AddDetails", sender: self)

... 和:

DispatchQueue.main.async {
   performSegue(withIdentifier: "AddDetails", sender: self)
}

一切正常。

但:

  1. 我不明白发生了什么。
  2. 我无法评估我正在做的事情是否是线程安全的。例如:我是否在 TVC2 关闭和 TVC1 同时调用 TVC2 之间引入了竞争条件?

谁能照亮正在发生的事情?

4

1 回答 1

0

Paulw11 在评论中提供了答案:

最好的方法是在每次调用 TVC2 后按下“添加另一个”按钮时不要放松。

相反,“添加另一个”按钮应该被控制拖动到同一个导航控制器并以模态方式进行呈现。

在 prepareForSegue 中,TVC2 需要的细节可以从当前的 ViewController 复制到它自己的新实例中。

在某些时候,用户使用工具栏中的 CANCEL 或 SAVE 按钮,这会将所有内容展开到 TVC1。

这样做也使 UI 看起来更干净,因为 TVC1 的展开是不可见的。

于 2017-11-02T22:41:07.613 回答