【问题标题】:Is it better practice to performSegueWithIdentifier or presentViewControllerperformSegueWithIdentifier 或 presentViewController 是更好的做法吗
【发布时间】:2019-10-17 23:10:37
【问题描述】:

如果我使用故事板,是创建一个 segue 并使用 performSegueWithIdentifier 还是只使用 presentViewController 将用户从一个 View Controller 移动到下一个 View Controller 是更好的做法。

对于这个示例,假设我们使用的是 Swift 5,并且我有 2 个视图控制器:MainViewController 上的联系人 TableView 和 DetailViewController 上联系人的详细信息。

在我的代码中,我使用的是 presentViewController,但由于我是 iOS 开发新手,我不确定这是否是最好的方法。

【问题讨论】:

  • 如果你使用两个 storyboards 你必须使用presentViewController,如果你使用一个包含两个视图控制器的故事板味道。
  • @vadian,即使有两个 故事板,您也可以拖出 故事板参考 对象来代替第二个故事板中的 VC,并使用正常转场。
  • @vacawama 真的吗?很高兴知道,你生活和学习。 ??????
  • @vadian,这就是我们都在这里的原因。不可能知道一切,尤其是当苹果不断改变事物时。 ;-)
  • 我认为这更像是一个个人决定,根据我的经验,我根本不喜欢使用 segues

标签: ios swift storyboard segue


【解决方案1】:

他们都做同样的事情,但我通常使用 Present 所以当我想改变行为时,例如,让按钮打开另一个 VC,我只需更改标识符,我不必删除 segue 和创建一个新的。 还有很多segues会让你的故事板看起来像意大利面条

【讨论】:

    【解决方案2】:

    为了便于说明,我们假设情节提要中的情况如下:

    ViewController1
        |----> modal segue "toVC2" emanating from ViewController1
            |----> ViewController2, identifier "VC2"
    

    那么在 ViewController1 代码中,这两件事之间绝对没有功能或有效的区别:

    • 使用标识符"toVC2" 调用performSegue
    • 在情节提要上使用标识符"VC2" 调用instantiateViewController 并调用present

    话虽如此,我会为每一种方式都比另一种方式“更好”提出一个理由。

    为什么 segue 可能会更好

    我的示例中的 segue 看起来并没有好多少,因为我们仍然需要使用代码来调用 performSegue。但是,假设 segue 不是来自视图控制器,而是来自视图控制器视图中的 button。这是一个 action 转场,现在转场将在用户点击我们的按钮时自动执行,而 无需代码 来执行它。您甚至不需要知道标识符。 (字符串标识符是犯错的好方法。)

    为什么instantiatepresent 可能会更好

    segue 有一些非常可怕的地方,无论是动作 segue 还是使用 performSegue 手动触发的 segue ——也就是说,当(经常发生)您想要将数据从第一个视图控制器传递到第二个时。如果使用 segue,则必须在 prepare(for:sender:) 的实现中进行数据传递。这非常麻烦,因为您必须检查 segue 标识符并将目的地转换为正确的类。此外,如果有多个 segue,prepare 就会成为一个混乱的瓶颈。如果我们也调用performSegue,我们在两个不同的地方运行——我们调用performSegue的方法,以及prepare的单独实现。

    相比之下,如果我们调用instantiateViewController,返回给我们的是视图控制器实例本身。我们仍然需要强制转换,但现在我们可以立即传递数据,而无需“等待”prepare,也不会遇到瓶颈。因此,这是一种更加清晰和封装的方式。

    另外,这似乎很明显,但是说present 的好处是它在代码中告诉我们转换是什么。如果您只使用一个转场标识符,那么这是一个模态转场这一事实将隐藏在情节提要中。

    我更喜欢哪个?

    两者都没有。如果我能提供帮助,我宁愿完全不使用故事板来呈现视图控制器。我使用视图控制器和同名笔尖。这样,我只需实例化视图控制器本身并将数据和present 传递给它,无需转换,也不需要任何标识符。

    我是说故事板一点都不好?

    没有。故事板具有绘制应用程序场景结构的优点,尤其是在您使用转场时。但是,如果您打算对视图控制器使用 segue,那么我首先看不到将视图控制器保留在情节提要中的意义。同名笔尖机制更清晰,更干净。此外,我认为prepare(for:sender:) 机制是整个故事板架构中近乎致命的缺陷; Stack Overflow 上显示的绝大多数错误都是此缺陷造成的。

    [编辑请注意,我对 segues 的许多反对意见将在 iOS 13 中消失,在 iOS 13 中,源视图控制器将能够使用代码调用目标视图控制器的初始化程序。]

    【讨论】:

    • 马特,你为什么认为prepare(for:sender:)是个缺陷?
    • @matt,谢谢。这很有帮助。当我开始这个应用程序时,我从 segues 和多个 VC 开始。我有大约 5 个 VC,包括一个菜单。该应用程序现在正在扩展,我想知道如何处理 20 个 VC。但现在我发现,根据菜单/导航中选择的内容,使用 1 个 VC 用于“细节”场景会更好地使用各种 xib。
    • 马特,我承认,我只扫描了你的答案。我回去阅读了prepare(for:sender:) 的邪恶部分。为了更干净地处理这个问题,我要做的一件事是在目标视图控制器的 class 上使用 switch 语句:switch segue.destination { 然后case let detailViewController as DetailViewController: <code>...case let otherVC as OtherVC: <code>。它使用目标的类来选择要执行的代码块,将目标转换为同一表达式中所需的类型,并将不同的代码块分解为案例。
    • 如果你想变得更高级,你可以构建一个字典,其中目标 VC 的类型作为键,闭包作为值,并使用触发 segue 的代码进行设置。跨度>
    • 我不太喜欢 segue 的另一个原因是,您必须为所需的每个源/目标链接设置不同的 segue,并且通过复杂的视图控制器排列,您可以使用 segue链接变成了一堆蜘蛛网。
    猜你喜欢
    • 1970-01-01
    • 2014-12-15
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多