添加完成处理程序到PresentViewControllerAsSheet(NSViewController)? [英] Add completion handler to presentViewControllerAsSheet(NSViewController)?

查看:587
本文介绍了添加完成处理程序到PresentViewControllerAsSheet(NSViewController)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的主窗口/视图控制器(我正在使用故事板)提供一个工作表配置视图( AddSoundEffect ),当配置视图控制器取消选择 AddSoundEffect 视图中输入的值,然后将其传回主视图。我目前在主视图控件中的代码:

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

AddSoundViewController.swift 文件中,代码要解除它是:

  self.dismissViewController(self)

要传递数据,我有一个类独立的元组,我保存数据。如何添加完成处理程序到 presentViewControllerAsSheet 和(可选)是否有更好的方式在视图控制器之间传递数据?



设置:Xcode版本6.4,OS X 10.10.4

解决方案

委托模式是您最简单的方法。

  //将此替换为您的元组或任何数据表示您的声音效果
struct SoundEffect {}

协议AddSoundViewControllerDelegate:class {
func soundViewController(控制器:AddSoundViewController,didAddSoundEffect:SoundEffect)
}

//
//让我们说这个控制器是一个模态视图控制器,用于添加新的声音效果
//
class AddSoundViewController:UIViewController {
weak var delegate:AddSoundViewControllerDelegate?

func done(发件人:AnyObject){
//虚拟音效信息,用自己的数据替换
let soundEffect = SoundEffect()

//
//每当您想通知呈现视图控制器
//关于添加的声音效果(在完成,添加,...按钮的情况下,调用它),不要调用它
//当用户点击取消只是关闭AddSoundViewController)
//
self.delegate?.soundViewController(self,didAddSoundEffect:soundEffect)

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

//
//让我们说这个控制器是主视图控制器,其中包含所有声音效果的列表,
//与按钮通过AddSoundViewController添加新的声音效果
//
class SoundEffectsViewController:UIViewController,AddSoundViewControllerDelegate {
func presentAddSoundEffectController(sender:AnyObject) {
如果允许addS oundController = self.storyboard?.instantiateViewControllerWithIdentifier(AddSoundEffect)为? AddSoundViewController {
addSoundController.delegate = self
self.presentViewController(addSoundController,animated:true,completion:{})
}
}

func soundViewController (控制器:AddSoundViewController,didAddSoundEffect:SoundEffect){
//仅当添加新的声音效果时才调用此方法
}
}
pre>

另一种方法是使用闭包:

  //替换这与你的元组或任何数据代表你的声音效果
struct SoundEffect {}

//
//让我们说这个控制器是一个模态视图控制器,用于添加新的音效
//
class AddSoundViewController:UIViewController {
var completionHandler:((SoundEffect) - >())?

func done(发件人:AnyObject){
//虚拟音效信息,用自己的数据替换
let soundEffect = SoundEffect()

//
//每当您想通知呈现视图控制器
//关于添加的声音效果(在完成,添加,...按钮的情况下,调用它),不要调用它
//当用户点击取消只是关闭AddSoundViewController)
//
self.completionHandler?(soundEffect)

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

//
//让我们说这个控制器是主视图控制器,其中包含所有声音效果的列表,
//与按钮添加新的声音效果通过AddSoundViewController
//
class SoundEffectsViewController:UIViewController {
func presentAddSoundEffectController(sender:AnyObject){
if let addSoundController = self.storyboard?.instantiateViewControllerWithIdent ifier(AddSoundEffect)为? AddSoundViewController {
addSoundController.completionHandler = {[weak self](soundEffect) - > ()in
//当添加新的声音效果时调用
}
self.presentViewController(addSoundController,animated:true,completion:{})
}
}
}

或许多其他方式,如发送通知,...无论适合您的需要。但是,在这种具体情况下,代理模式或关闭是最好的方法。






我错过了你的问题是关于 NSViewController 。这个例子适用于iOS,但在OS X上可以使用相同的模式,而不会出现任何问题。


I am attempting to present a sheet configuration view (AddSoundEffect) for my main window/view controller (I'm using storyboards), and when the configuration view controller is dismissed, take the values entered in the AddSoundEffect view and pass that back to the main view. My current code in the main view controller:

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

And in the AddSoundViewController.swift file, the code to dismiss it is:

self.dismissViewController(self)

To pass the data, I have a class-independent tuple that I save data to. How do I add a completion handler to presentViewControllerAsSheet, and (optionally) is there a better way to pass the data between view controllers?

Setup: Xcode version 6.4, OS X 10.10.4

解决方案

Delegation pattern is the easiest way for you.

// 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
  }
}

Another way is to use closures:

// 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: {})
    }
  }
}

Or many other ways like sending notification, ... Whatever suits your needs. But delegation pattern or closures is the best way to go in this specific case.


I missed that your question is about NSViewController. This example is for iOS, but same pattern can be used on OS X without any issues.

这篇关于添加完成处理程序到PresentViewControllerAsSheet(NSViewController)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆