将完成处理程序添加到 presentViewControllerAsSheet(NSViewController)?
Add completion handler to presentViewControllerAsSheet(NSViewController)?
我正在尝试为我的主 window/view 控制器(我正在使用故事板)呈现一个 sheet 配置视图 (AddSoundEffect
),当配置视图控制器被关闭时,获取在 AddSoundEffect
视图中输入的值并将其传递回主视图。我在主视图控制器中的当前代码:
presentViewControllerAsSheet(self.storyboard!.instantiateControllerWithIdentifier("AddSoundEffect") as! AddSoundViewController
并且在 AddSoundViewController.swift
文件中,关闭它的代码是:
self.dismissViewController(self)
为了传递数据,我有一个 class 独立的元组来保存数据。如何向 presentViewControllerAsSheet
添加完成处理程序,以及(可选)是否有更好的方法在视图控制器之间传递数据?
设置:Xcode 版本 6.4,OS X 10.10.4
Delegation 模式对您来说是最简单的方法。
// 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: {})
}
}
}
或许多其他方式,例如发送通知,...任何适合您需要的方式。但是在这种特定情况下,委托模式或闭包是最好的方法。
我没注意到你的问题是关于 NSViewController
的。此示例适用于 iOS,但可以在 OS X 上使用相同的模式而不会出现任何问题。
检测 sheet 打开或关闭的最简单方法是使用 Sheet Notifications:
class ViewController: NSViewController, NSWindowDelegate {
override func viewDidLoad(){
NSApplication.sharedApplication().windows.first?.delegate = self
}
func windowDidEndSheet(notification: NSNotification) {
}
func windowWillBeginSheet(notification: NSNotification) {
}
}
我正在尝试为我的主 window/view 控制器(我正在使用故事板)呈现一个 sheet 配置视图 (AddSoundEffect
),当配置视图控制器被关闭时,获取在 AddSoundEffect
视图中输入的值并将其传递回主视图。我在主视图控制器中的当前代码:
presentViewControllerAsSheet(self.storyboard!.instantiateControllerWithIdentifier("AddSoundEffect") as! AddSoundViewController
并且在 AddSoundViewController.swift
文件中,关闭它的代码是:
self.dismissViewController(self)
为了传递数据,我有一个 class 独立的元组来保存数据。如何向 presentViewControllerAsSheet
添加完成处理程序,以及(可选)是否有更好的方法在视图控制器之间传递数据?
设置:Xcode 版本 6.4,OS X 10.10.4
Delegation 模式对您来说是最简单的方法。
// 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: {})
}
}
}
或许多其他方式,例如发送通知,...任何适合您需要的方式。但是在这种特定情况下,委托模式或闭包是最好的方法。
我没注意到你的问题是关于 NSViewController
的。此示例适用于 iOS,但可以在 OS X 上使用相同的模式而不会出现任何问题。
检测 sheet 打开或关闭的最简单方法是使用 Sheet Notifications:
class ViewController: NSViewController, NSWindowDelegate {
override func viewDidLoad(){
NSApplication.sharedApplication().windows.first?.delegate = self
}
func windowDidEndSheet(notification: NSNotification) {
}
func windowWillBeginSheet(notification: NSNotification) {
}
}