以下代码应显示两种使用Responder Chain OR委托方法将信息从嵌入式控制器(UICollectionView)传递回详细视图控制器的方法。两种方法都使用相同的协议和委托方法。唯一的区别是如果我在didSelectItemAtIndex路径中注释了委托?.method行,则响应者链工作。但是,如果我在didSelectItemAtIndex方法中注释了Responder Chain行,那么这个未知的委托?财产不会调用该方法,并且仍为零。
协议定义并包含在DetailViewController之上。这两种方法都需要。
protocol FeatureImageController: class {
func featureImageSelected(indexPath: NSIndexPath)
}
在自定义UICollectionViewController类中声明的委托属性,仅用于委托方法。
class PhotoCollectionVC: UICollectionViewController
{
weak var delegate: FeatureImageController?
在DetailViewController中,创建了一个PhotoCollectionVC()实例,并将委托属性设置为self,并将委托协议作为类型。
class DetailViewController: UIViewController, FeatureImageController
{...
override func viewDidLoad() {
super.viewDidLoad()
let photoCollectionVC = PhotoCollectionVC()
photoCollectionVC.delegate = self as FeatureImageController
在集合视图控制器的didSelectItemAtIndexPath方法中,通过Responder Chain(已注释掉)或委托给DetailVC中的featureImageSelected方法传回所选的indexPath。
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
// if let imageSelector = targetForAction("featureImageSelected:", withSender: self) as? FeatureImageController {
// imageSelector.featureImageSelected(indexPath)
// }
self.delegate?.featureImageSelected(indexPath)
}
DetailViewController中的elegate方法实例。两者都需要。
func featureImageSelected(indexPath: NSIndexPath) {
record?.featureImage = record?.images[indexPath.row]
self.configureView()
}
为什么响应者链方法可行,但代表不是?
没有编译器或运行时错误。在didSelectItemAtIndexPath方法中,委托总是返回nil,并且没有从委托方法打印任何内容。
答案 0 :(得分:0)
您的响应者代码调用self:
上的featureImageSelectedself.featureImageSelected(indexPath)
但委托代码在委托上调用featureImageSelected:
self.delegate.featureImageSelected(indexPath)
这将是DetailVC的委托,而不是collectionViews委托。我不确定你的代码在做什么,但你可能想要像
这样的东西collectionView.delegate?.featureImageSelected(IndexPath)
看起来它最终会成为
self.featureImageSelected(indexPath)
答案 1 :(得分:0)
问题中的错误是,在符合的类中,"创建了PhotoCollectionVC()的实例,并将delegate属性设置为self"。在viewDidLoad中,它只是创建了另一个具有永远不会被调用的无关委托属性的实例。实际嵌入式PhotoCollectionVC的委托属性需要分配给自己 - 以便两个VC进行通信。这是在prepareForSegue方法中完成的:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
...
let controller = (segue.destinationViewController as! PhotoCollectionVC)
...
controller.delegate = self
}
}
}
示例代码的其余部分没问题。
以下是从嵌入式容器到其委托VC的委派的一个非常简单的示例。嵌入式容器只是告诉VC按下了一个按钮。故事板只是一个VC,里面有一个容器和一个文本插座。在容器VC中,只有一个按钮。而segue有一个标识符。
委托ViewController中的代码是:
protocol ChangeLabelText: class
{
func changeText()
}
class ViewController: UIViewController, ChangeLabelText
{
@IBOutlet weak var myLabel: UILabel!
override func viewDidLoad()
{
super.viewDidLoad()
myLabel?.text = "Start"
}
func changeText()
{
myLabel?.text = "End"
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "feelTheBern"
{
let secondVC: myViewController = segue.destinationViewController as! myViewController
secondVC.delegate = self
}}
}
委托视图控制器myViewController中的代码是:
class myViewController: UIViewController
{
weak var delegate: ChangeLabelText?
@IBAction func myButton(sender: AnyObject)
{
print("action")
delegate?.changeText()
}
override func viewDidLoad() {
super.viewDidLoad()
}
}