[英]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.