【问题标题】:Add completion handler to presentViewControllerAsSheet(NSViewController)?将完成处理程序添加到 presentViewControllerAsSheet(NSViewController)?
【发布时间】:2015-07-16 05:13:21
【问题描述】:

我正在尝试为我的主窗口/视图控制器(我正在使用情节提要)呈现一个工作表配置视图 (AddSoundEffect),当配置视图控制器被关闭时,获取在 AddSoundEffect 中输入的值查看并将其传递回主视图。我当前在主视图控制器中的代码:

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

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

self.dismissViewController(self)

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

设置:Xcode 6.4 版,OS X 10.10.4

【问题讨论】:

    标签: macos swift event-handling nsviewcontroller


    【解决方案1】:

    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 上使用而不会出现任何问题。

    【讨论】:

    • 我与NSViewControllers 合作,而不是UIViewControllers。这会以同样的方式工作吗?
    • 是的,没有任何问题。这些是 iOS 和 OS X 上常用的模式。
    【解决方案2】:

    检测工作表打开或关闭的最简单方法是使用Sheet Notifications

    class ViewController: NSViewController, NSWindowDelegate {
    
        override func viewDidLoad(){
            NSApplication.sharedApplication().windows.first?.delegate = self
        }
        func windowDidEndSheet(notification: NSNotification) {
    
        }
        func windowWillBeginSheet(notification: NSNotification) {
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多