macos - 将完成处理程序添加到 presentViewControllerAsSheet(NSViewController)?

标签 macos swift event-handling nsviewcontroller

我正在尝试为我的主窗口/ View Controller (我使用的是 Storyboard )呈现工作表配置 View (AddSoundEffect),当配置 View Controller 被关闭时,获取输入的值在 AddSoundEffect View 中并将其传递回主视图。我在主视图 Controller 中的当前代码:

presentViewControllerAsSheet(self.storyboard!.instantiateControllerWithIdentifier("AddSoundEffect") as! AddSoundViewController

AddSoundViewController.swift 文件中,关闭它的代码是:

self.dismissViewController(self)

为了传递数据,我有一个类无关的元组来保存数据。如何向 presentViewControllerAsSheet 添加完成处理程序,以及(可选)是否有更好的方法在 View Controller 之间传递数据?

设置:Xcode 版本 6.4,OS X 10.10.4

最佳答案

Delegation pattern 是最简单的方法。

// Replace this with your tuple or whatever data represents your sound effect
struct SoundEffect {}

protocol AddSoundViewControllerDelegate: class {
  func soundViewController(controller: AddSoundViewController, didAddSoundEffect: SoundEffect)
}

//
// Let's say this controller is a modal view controller for adding new sound effects
//
class AddSoundViewController: UIViewController {
  weak var delegate: AddSoundViewControllerDelegate?

  func done(sender: AnyObject) {
    // Dummy sound effect info, replace it with your own data
    let soundEffect = SoundEffect()

    //
    // Call it whenever you would like to inform presenting view controller
    // about added sound effect (in case of Done, Add, ... button tapped, do not call it
    // when user taps on Cancel to just dismiss AddSoundViewController)
    //
    self.delegate?.soundViewController(self, didAddSoundEffect: soundEffect)

    // Dismiss self
    self.dismissViewControllerAnimated(true, completion: {})
  }
}

//
// Let's say this controller is main view controller, which contains list of all sound effects,
// with button to add new sound effect via AddSoundViewController
//
class SoundEffectsViewController: UIViewController, AddSoundViewControllerDelegate {
  func presentAddSoundEffectController(sender: AnyObject) {
    if let addSoundController = self.storyboard?.instantiateViewControllerWithIdentifier("AddSoundEffect") as? AddSoundViewController {
      addSoundController.delegate = self
      self.presentViewController(addSoundController, animated: true, completion: {})
    }
  }

  func soundViewController(controller: AddSoundViewController, didAddSoundEffect: SoundEffect) {
    // This method is called only when new sound effect is added
  }
}

另一种方法是使用闭包:

// Replace this with your tuple or whatever data represents your sound effect
struct SoundEffect {}

//
// Let's say this controller is a modal view controller for adding new sound effects
//
class AddSoundViewController: UIViewController {
  var completionHandler: ((SoundEffect) -> ())?

  func done(sender: AnyObject) {
    // Dummy sound effect info, replace it with your own data
    let soundEffect = SoundEffect()

    //
    // Call it whenever you would like to inform presenting view controller
    // about added sound effect (in case of Done, Add, ... button tapped, do not call it
    // when user taps on Cancel to just dismiss AddSoundViewController)
    //
    self.completionHandler?(soundEffect)

    // Dismiss self
    self.dismissViewControllerAnimated(true, completion: {})
  }
}

//
// Let's say this controller is main view controller, which contains list of all sound effects,
// with button to add new sound effect via AddSoundViewController
//
class SoundEffectsViewController: UIViewController {
  func presentAddSoundEffectController(sender: AnyObject) {
    if let addSoundController = self.storyboard?.instantiateViewControllerWithIdentifier("AddSoundEffect") as? AddSoundViewController {
      addSoundController.completionHandler = { [weak self] (soundEffect) -> () in
        // Called when new sound effect is added
      }
      self.presentViewController(addSoundController, animated: true, completion: {})
    }
  }
}

或许多其他方式,例如发送通知,...任何适合您需要的方式。但在这种特定情况下,委托(delegate)模式或闭包是最好的方法。


我没有注意到您的问题是关于 NSViewController 的。此示例适用于 iOS,但可以在 OS X 上使用相同的模式而不会出现任何问题。

关于macos - 将完成处理程序添加到 presentViewControllerAsSheet(NSViewController)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31445785/

相关文章:

ios - 带分页的水平 ScrollView 中的全宽标签

swift - 为什么我现在必须在 Swift 中覆盖我的 init?

forms - VBA:在用户窗体上使用WithEvents

c# - 事件与 while(true) 循环

macos - 如何在 macOS 上安装 Mono 以便 Mono 在终端中运行?

macos - 如何修改 NSButton 的外观以创建切换效果

c - Mac 内核编程通用内核扩展 prinf() 不工作

ios - Swift UISplitViewController MasterViewController 设置宽度不起作用

java - 在定时器开始触发后重新设置延迟

objective-c - 如何给 NSText 多个阴影?