故事板 Segue 与委派。哪种方法更适合在 ViewController 之间传递数据

Posted

技术标签:

【中文标题】故事板 Segue 与委派。哪种方法更适合在 ViewController 之间传递数据【英文标题】:Storyboard Segue vs Delegation. Which method is better for passing data between ViewControllers 【发布时间】:2018-03-27 08:48:14 【问题描述】:

我是 ios 的新手,想知道使用哪种方法在 ViewController 之间传递数据。我更喜欢 segues,因为仅使用一行代码,您就可以获得对 ViewController 及其字段、方法等的引用……另一方面,委托是 ios 中的一个重要主题。我现在很困惑使用哪种方法。请解释一下。

【问题讨论】:

苹果和橙子。诚实地。对于初学者,您不能使用 segue,除非您在情节提要中定义它们。一旦你明白了,你需要问自己如何使用下一个视图控制器 - 呈现,子控制器,什么?这甚至没有提到为什么你要传递这个“数据”....是从一个主视图“segue”到下一个主视图吗?也许是在另一个视图的控制器中“通知”或“触发”一个动作?换句话说 - 您的具体问题是什么? 它们有不同的用途,除非您询问具体的 Unwind segue 与委派,否则您应该先 google 一下 【参考方案1】:

请认真回答我的问题,这在很大程度上取决于您使用的架构(MVC、MVP、VIPER 等)以及代码的组织方式


答案是:取决于你想要达到的目标。

转场

当您需要将数据从一个 UIViewController 传递到另一个 UIViewController 以便正确呈现时,您将使用 segues。它们是一种非常直接的方法。

代表团

当您需要让一个对象(例如,UIViewController)知道另一个对象(例如,另一个 UIViewController)中发生的动作时,您可以使用委托(以及其他)来实现这一点。

【讨论】:

委托是一种在不改变其来源的情况下扩展类功能的模式,即支持开闭原则的模式的教科书示例。不仅仅是为了通知对象事件。例如。在 UIKit 中,我们看到了诸如“索引路径行的高度”、“部分中的标题视图”、“应该这样做”、“应该那样做”等委托方法,以及其他允许您自定义控件外观和行为的方法无需更改其来源。 @JohnSnow 同意,但是,在问题的上下文中,我没有看到需要命名委托模式的充分使用【参考方案2】:

这是这两者的基本行为。我也包括通知,以便您可以区分委派和通知。将来您将几乎使用通知:Segue:当您必须将一些数据从一个UIViewController 发送到另一个时,这是最简单的方法。 VC! -> VC2。请记住,VC2 应该是导航层次结构中的下一个。委托:用于在事件触发时通知对象。示例 - 从 API 获取数据。接收数据时显示活动指示。当 API 完成它的工作时隐藏它。使用块或闭包可以非常轻松地实现此行为。注意:当您只需要通知一个对象时,这很有用。通知:用于当事件触发时通知一个对象。注意:这用于通知一个或多个对象。

【讨论】:

【参考方案3】:

我正在避免委托。我正在使用闭包将数据从 VC2 发送到 VC1,并将值从 VC1 设置为 VC2。 不要忘记在故事板或代码中使用 NavigationController

class VC1: UIViewController 
  var someValue1:Bool = false

  func viewDidLoad() 
    super.viewDidLoad()
  

  @IBAction func buttonTapped(_ sender:UIButton) 
    showVC2()
  

  func showVC2() 
    let vc = UIStoryboard(name: "PlaceTrackList", bundle: nil).instantiateInitialViewController() as! TrackListViewController
    vc.completionClosure  [weak self] someValueFromVC2 in
      // close when button tapped in VC2 and set value like in VC2
      self?.someValue1 = someValueFromVC2
      self?.navigationController?.popToViewController(self, animated: true)
    
    navigationController?.pushViewController(vc, animated: true)
  


class VC2: UIViewController 
  var someValue2:Bool = true
  completionClosure: ((Bool) -> Void)?

  func viewDidLoad() 
    super.viewDidLoad()
  

  @IBAction func VC2ButtonTapped(_ sender:UIButton) 
    completionClosure?(someValue2)
  


【讨论】:

【参考方案4】:

在数据传递方面

如果你想将数据从 VC1 传递到 VC2,这取决于你想传递数据的位置,而不是 segue 有用,但如果你想将数据从 VC2 传输到 VC1,那么这是你无法做到的为了实现这一点,您可以使用委托。

一般而言

委托 - 委托是与对象之间的一种通信方式,例如表格视图委托方法,当单元格被触摸时,您将收到通知

【讨论】:

以上是关于故事板 Segue 与委派。哪种方法更适合在 ViewController 之间传递数据的主要内容,如果未能解决你的问题,请参考以下文章

“Unwind Segue”可以在通过故事板参考连接的两个故事板之间工作吗?

当按钮逻辑失败时停止故事板中的 segue

Storyboard Segue 标识符命名约定

代表为零,使用故事板嵌入segue

故事板 segue 调用顺序

在多个故事板环境中展开 segue