简体   繁体   English

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

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

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. 下面的代码应显示两种使用“响应者链”或“委托”方法将信息从嵌入式控制器(UICollectionView)传递回详细视图控制器的方式。 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. 唯一的区别是,如果我注释掉didSelectItemAtIndex路径中的proxy..method行,则响应程序链将起作用。 BUT, if I comment out the Responder Chain line in the didSelectItemAtIndex method, the uncommentented delegate? 但是,如果我在didSelectItemAtIndex方法中注释掉“响应者链”行,该注释是否为未注释? property doesn't call the method, and remains nil. 属性不会调用该方法,而是保持为零。

Protocol defined and included above DetailViewController. 协议已定义并包含在DetailViewController之上。 Needed for both approaches. 两种方法都需要。

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

Delegate property declared in the custom UICollectionViewController class, which is only needed for delegate approach. 在自定义UICollectionViewController类中声明的Delegate属性,仅对于代理方法才需要。

class PhotoCollectionVC: UICollectionViewController
{
   weak var delegate: FeatureImageController?

In DetailViewController, an instance of PhotoCollectionVC() is created, and the delegate property set to self with the delegate protocol as type. 在DetailViewController中,创建PhotoCollectionVC()的实例,并将委托属性设置为self,并将委托协议作为类型。

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

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

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. 在集合视图控制器的didSelectItemAtIndexPath方法中,通过“响应者链”(注释掉)或委托将其传递回DetailVC中的featureImageSelected方法。

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
//    if let imageSelector =  targetForAction("featureImageSelected:", withSender: self) as? FeatureImageController {
//       imageSelector.featureImageSelected(indexPath)
//      }
        self.delegate?.featureImageSelected(indexPath)
}

An instance of elegate method in DetailViewController. DetailViewController中elegate方法的一个实例。 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? 为什么响应者链方法有效,但委托人无效?

There are no compiler or run time errors. 没有编译器或运行时错误。 Within the didSelectItemAtIndexPath method, the delegate always returns nil and nothing prints from the delegate method. 在didSelectItemAtIndexPath方法中,委托始终返回nil,并且委托方法没有任何输出。

Your responder code calls a featureImageSelected on self: 您的响应者代码对自己调用一个featureImageSelected:

self.featureImageSelected(indexPath)

but the delegate code calls featureImageSelected on the delegate: 但委托代码在委托上调用featureImageSelected:

self.delegate.featureImageSelected(indexPath)

Which would be the DetailVC's delegate, not the collectionViews delegate. 这将是DetailVC的委托,而不是collectionViews委托。 Im not really sure what your code is doing, but you probably want something like 我不太确定您的代码在做什么,但您可能想要类似

collectionView.delegate?.featureImageSelected(IndexPath)

which looks like it would just end up being 看起来就像最终会被

self.featureImageSelected(indexPath)

The error in the question is where, in the conforming class, "an instance of PhotoCollectionVC() is created, and the delegate property set to self". 问题中的错误是在合格的类中的哪里“创建PhotoCollectionVC()的实例,并将委托属性设置为self”。 In viewDidLoad, that just creates another instance with an irrelevant delegate property that will never be called. 在viewDidLoad中,这只会创建一个具有不相关委托属性的实例,该实例永远不会被调用。 The delegate property of the actual embedded PhotoCollectionVC needs to be assigned to self - in order for the two VCs to communicate. 实际的嵌入式PhotoCollectionVC的委托属性需要分配给self-以便两个VC进行通信。 This is done from within the prepareForSegue method: 这是从prepareForSegue方法中完成的:

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

The rest of the example code is fine. 示例代码的其余部分都很好。

Here is a super simple example of delegation from an embedded container to its delegate VC. 这是一个从嵌入式容器到其委托VC的超级简单示例。 The embedded container simply tells the VC that a button has been pressed. 嵌入式容器仅告诉VC按钮已被按下。 The story board is just a VC with a container in it and a text outlet. 故事板只是一个VC,其中包含一个容器和一个文本出口。 In the container VC, there is just a button. 在容器VC中,只有一个按钮。 And the segue has an identifier. 并且segue具有标识符。

The code in the delegate ViewController is: 委托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
        }}
}

The code in the delegating View Controller, myViewController, is: 委派的视图控制器myViewController中的代码为:

class myViewController: UIViewController
{
    weak var delegate: ChangeLabelText?

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 容器视图控制器委托分配 - Container View Controller delegate assignment 委托发送回值并推送弹出视图控制器 - Delegate send value back and push pop view controller 从另一个View Controller辞职第一响应者 - Resign First Responder from another View Controller 目标视图控制器上的简单委托方法或属性 - Simple delegate method or property on destination view controller 如何使用委托将数据从多个视图控制器传递回根视图控制器? IOS 7 - How to pass data back from multiple view controllers to root view controller using delegate? Ios 7 数据如何从视图控制器传递到另一个视图控制器 - How data passes from view controller to another view controller 代表 SwiftUI 从托管视图 Controller 查看 - Delegate for SwiftUI View from Hosting View Controller 在自定义容器视图控制器中调用endEditing会隐藏键盘,但不会更改键盘响应器 - Calling endEditing in custom container view controller hides keyboard but doesn't change keyboard responder 将数据从表格单元格发送到视图 controller 时,委托属性为空 - delegate property is nill while sending data from table cell to a view controller 使用ios中的自定义委托从另一个视图控制器更改一个视图控制器NSSdictonary的值 - Change value of one view controllers NSSdictonary from other view controller using custom delegate in ios
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM