响应链但不委托 属性 将值从容器传递回视图控制器

Responder Chain but NOT delegate property passes value back to view controller from container

以下代码应显示两种使用响应链或委托方法将信息从嵌入式控制器 (UICollectionView) 传递回详细视图控制器的方法。两种方法都使用相同的协议和委托方法。唯一的区别是,如果我在 didSelectItemAtIndex 路径中注释掉 delegate?.method 行,则响应链会起作用。但是,如果我在 didSelectItemAtIndex 方法中注释掉 Responder Chain 行,未注释的委托? 属性 不调用该方法,并保持为零。

在 DetailViewController 之上定义并包含的协议。两种方法都需要。

protocol FeatureImageController: class {
func featureImageSelected(indexPath: NSIndexPath)
}

在自定义 UICollectionViewController class 中声明的委托 属性,只有委托方法才需要。

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 方法中,通过响应链(已注释掉)或委托给 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 中委托方法的一个实例。两者都需要。

func featureImageSelected(indexPath: NSIndexPath) {
    record?.featureImage = record?.images[indexPath.row]
    self.configureView()
}

为什么 Responder Chain 方法有效,但委托无效?

没有编译器或 运行 时间错误。在 didSelectItemAtIndexPath 方法中,委托总是 returns nil 并且委托方法不打印任何内容。

您的响应程序代码调用自己的 featureImageSelected:

self.featureImageSelected(indexPath)

但是委托代码在委托上调用 featureImageSelected:

self.delegate.featureImageSelected(indexPath)

这将是 DetailVC 的委托,而不是 collectionViews 委托。我不太确定你的代码在做什么,但你可能想要

collectionView.delegate?.featureImageSelected(IndexPath)

看起来它最终会变成

self.featureImageSelected(indexPath)

题中的错误是where, in the conforming class, "an instance of PhotoCollectionVC() is created, and the delegate property set to self".在 viewDidLoad 中,这只是创建了另一个实例,其中包含一个永远不会被调用的无关委托 属性。实际嵌入的 PhotoCollectionVC 的委托 属性 需要分配给 self - 以便两个 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
        }}
}

委托视图控制器中的代码,我的ViewController,是:

class myViewController: UIViewController
{
    weak var delegate: ChangeLabelText?

    @IBAction func myButton(sender: AnyObject)
    {
        print("action")
        delegate?.changeText()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}