通过在嵌入式容器中的集合视图中选择一个单元格来更改视图控制器中的值/图像

Change value / image in view controller by selecting a cell within a collection view within an embedded container

在详细视图控制器中,我在左上角有一个 'featureImage',在其下方有一个细水平图像条。图像条是由自定义 CollectionViewController 管理的嵌入式容器视图,它显示图像数组。初始 featureImage 是 images[0] 数组中的第一个图像,并将相同的数组传递给集合视图。

如果选择/点击容器视图中的单元格,我希望 featureImage 更新为同一图像。

我想我需要调用委托方法 didSelectItemAtIndexPath,它会给我 indexPath。正确的?但是我如何将已经来自委托的 indexPath 传递回详细视图控制器。

已编辑 - 该代码显示了响应链和委托方法之间的代码重叠和差异。在 didSelectItemAtIndex 路径中取消注释,响应链方法有效,而委托方法无效。

协议定义并包含在 DetailViewController 的顶部(我似乎并不关心协议在哪个文件中,并且只输入 class 以允许委托 属性 'weak').两种方法都需要。

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

在自定义 UICollectionViewController class 中声明的委托 属性。仅委托方法需要。

 weak var delegate: FeatureImageController?

委托 属性 在 DetailViewController 中启动。仅委托方法需要。

    override func viewDidLoad() {
    super.viewDidLoad()

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

集合视图控制器 didSelectItemAtIndexPath 方法中的响应者链(活动)或委托方法(注释掉)。

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

根据我的经验,View Controller 之间的数据选择通信最好通过两种方式实现——委托或响应链路由。无论哪种方式,第一步都是创建您的 DetailViewController 将遵守的协议。类似于:

protocol FeatureImageController: class {
    func featureImageSelected(image: UIImage)
}

您的 DetailViewController 然后将实现此功能并使用它来更改 'feature image'。那么如何传达取决于您是使用委托还是响应者链。

委派 如果您更喜欢使用委托,那么在您的 CollectionViewController 上声明一个委托 属性,如下所示:

weak var delegate: FeatureImageController?

然后在 didSelectItemAtIndexPath 中,您将使用提供的 indexPath 确定所选图像并将其传递给您的委托人:

delegate?.featureImageSelected(selectedImage)

其中 selectedImage 是从集合视图中选择的图像。

响应链 如果您决定使用响应者链,则无需声明委托 属性。相反,您会要求第一个响应您的协议方法的目标。所以在 didSelectItemAtIndexPath 里面你会说:

if let imageController = targetForAction("featureImageSelected:", withSender: self) as? FeatureImageController {
   imageController.featureImageSelected(selectedImage)
}

这两种方法(委托或响应链)都允许集合视图控制器将其选择传递给细节控制器。委托路由在 Framework 中更为常见,但我发现当我们更频繁地在容器中使用容器时,在没有我不满意的 'coupling' 数量的情况下正确管理委托链变得非常讨厌。另一方面,框架已经提供了响应者链 'dig' 到控制器的层次结构中,以找到愿意处理您的操作的人。