以下是建议委托流程的代码......
在主视图控制器中......
protocol FilterDelegate: class {
func onRedFilter()
func onGreenFilter()
func onBlueFilter()
func onUnfiltered()
}
class ViewController: UIViewController, FilterDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
----
// Increase red color level on image by one.
func onRedFilter() {
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "filterSegue" {
let dest = segue.destinationViewController as! CollectionViewController
dest.filterDelegate = self
}
}
集合视图控制器中的......
var filterDelegate: FilterDelegate?
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print("Cell \(indexPath.row) selected")
guard let filterDelegate = filterDelegate else {
print("Filter delegate wasn't set!")
return
}
switch indexPath.row {
case 0:
filterDelegate.onRedFilter()
case 1:
filterDelegate.onGreenFilter()
case 2:
filterDelegate.onBlueFilter()
case 3:
filterDelegate.onUnfiltered()
default:
print("No available filter.")
}
现在......代码在保护块处停止并打印错误消息。任何按下单元格都不会执行开关块。
答案 0 :(得分:0)
您在倒数第二句中的理论是正确的 - 当您在“子”视图控制器中调用storyboard.instantiateViewControllerWithIdentifier
时,您实际上是在创建一个全新的主视图控制器实例。您不获取对现有主视图控制器的引用,这就是您调用的方法没有任何效果的原因。
有几种方法可以实现您的目标,包括delegate pattern或使用闭包。以下是使用委托协议的概述:
protocol FilterDelegate: class {
func onRedFilter()
func onGreenFilter()
func onBlueFilter()
func onUnfiltered()
}
class MainViewController: UIViewController, FilterDelegate {
// implement these as required
func onRedFilter() { }
func onGreenFilter() { }
func onBlueFilter() { }
func onUnfiltered() { }
// when we segue to the child view controller, we need to give it a reference
// to the *existing* main view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let dest = segue.destination as? ChildViewController {
dest.filterDelegate = self
}
}
}
class ChildViewController: UIViewController {
var filterDelegate: FilterDelegate?
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
// ...
guard let filterDelegate = filterDelegate else {
print("Filter delegate wasn't set!")
return
}
switch indexPath.row {
case 0:
filterDelegate.onRedFilter()
case 1:
filterDelegate.onGreenFilter()
case 2:
filterDelegate.onBlueFilter()
case 3:
filterDelegate.onUnfiltered()
default:
print("No available filter.")
}
}
}
另一种选择是在ChildViewController
上为孩子需要调用的MainViewController
上的每个函数提供闭包,并在prepareForSegue
中设置它们。使用委托看起来有点干净,因为在这种情况下有很多函数。