响应者链,但未委托属性将值返回到从容器中查看控制器 [英] Responder Chain but NOT delegate property passes value back to view controller from container

查看:129
本文介绍了响应者链,但未委托属性将值返回到从容器中查看控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The following code should show two ways to pass information from an embedded controller (UICollectionView) back to a detailed view controller using either the Responder Chain OR delegate approach. Both approaches use the same protocol, and delegate method. The only difference is if I comment out the delegate?.method line in didSelectItemAtIndex path, the Responder Chain works. BUT, if I comment out the Responder Chain line in the didSelectItemAtIndex method, the uncommentented delegate? property doesn't call the method, and remains nil.

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

Protocol defined and included above DetailViewController. Needed for both approaches.

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

在自定义UICollectionViewController类中声明的委托属性,仅用于委托方法。

Delegate property declared in the custom UICollectionViewController class, which is only needed for delegate approach.

class PhotoCollectionVC: UICollectionViewController
{
   weak var delegate: FeatureImageController?

在DetailViewController中,创建了PhotoCollectionVC()的一个实例,并将委托属性设置为self委托协议作为类型。

In DetailViewController, an instance of PhotoCollectionVC() is created, and the delegate property set to self with the delegate protocol as type.

class DetailViewController: UIViewController, FeatureImageController 
{...
    override func viewDidLoad() {
    super.viewDidLoad()

    let photoCollectionVC = PhotoCollectionVC()
    photoCollectionVC.delegate = self as FeatureImageController

在集合视图控制器的didSelectItemAtIndexPath方法中,通过Responder Chain(注释掉)或将代理返回到DetailVC中的featureImageSelected方法。

Within the collection view controller's didSelectItemAtIndexPath method, pass back the selected indexPath via either the Responder Chain (commented out) OR the delegate to the featureImageSelected method in the DetailVC.

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方法的一个实例。需要两个。

An instance of elegate method in DetailViewController. Needed for both.

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

为什么响应者链方式工作,但不是代理?

Why would the Responder Chain approach work, but the delegate not?

没有编译器或运行时错误。在didSelectItemAtIndexPath方法中,委托总是从委托方法返回零,没有打印。

There are no compiler or run time errors. Within the didSelectItemAtIndexPath method, the delegate always returns nil and nothing prints from the delegate method.

推荐答案

问题的错误在于在一致的类中,创建了PhotoCollectionVC()的一个实例,并将委托属性设置为self。在viewDidLoad中,只需创建一个不相关委托属性的另一个实例,该属性将永远不会被调用。实际嵌入式PhotoCollectionVC的委托属性需要分配给自身才能使两个VC进行通信。这是从prepareForSegue方法中完成的:

The error in the question is where, in the conforming class, "an instance of PhotoCollectionVC() is created, and the delegate property set to self". In viewDidLoad, that just creates another instance with an irrelevant delegate property that will never be called. The delegate property of the actual embedded PhotoCollectionVC needs to be assigned to self - in order for the two VCs to communicate. This is done from within the prepareForSegue method:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
    ...
        let controller =  (segue.destinationViewController as! PhotoCollectionVC)
        ...
        controller.delegate = self
        }
    }
}

其余的示例代码很好。

这是从嵌入式容器委托给VC的一个超简单示例。嵌入式容器只是告诉VC一个按钮被按下。故事板只是一个带有容器的VC和一个文本插座。在容器VC中,只有一个按钮。而segue有一个标识符。

Here is a super simple example of delegation from an embedded container to its delegate VC. The embedded container simply tells the VC that a button has been pressed. The story board is just a VC with a container in it and a text outlet. In the container VC, there is just a button. And the segue has an identifier.

代理ViewController中的代码是:

The code in the delegate ViewController is:

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

View Controller,myViewController中的代码是:

The code in the delegating View Controller, myViewController, is:

class myViewController: UIViewController
{
    weak var delegate: ChangeLabelText?

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

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

这篇关于响应者链,但未委托属性将值返回到从容器中查看控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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