【问题标题】:Access a UICollectionView's parent UIViewController访问 UICollectionView 的父 UIViewController
【发布时间】:2017-06-05 16:17:28
【问题描述】:

我的问题很简单。我有一个包含 UICollectionView 的 UIViewController。在初始化我的单元格时,我为每个单元格添加了一个手势识别器,以便当您点击并按住它时,它会调用一个带有选择器的函数。

然后这个函数会创建一个我想要展示的 UIAlertController。 (基本上,您持有一个单元格,它会询问您是否要删除它,如果您说是,它会从 CollectionView 中删除它)

问题是我无法从我的 UICollectionView 中显示 UIAlertController,因为它不是 ViewController。

我想以编程方式获取包含 UICollectionView 的 UIViewController,以从 UICollectionView 实现中的函数显示此警报。

【问题讨论】:

  • 能否请您发布一些代码?只需创建类的代码以及创建 UIAlert 的位置即可
  • 子类化UICollectionView 以保存weak delegate: UIViewController? 字段,并在视图控制器中使用collectionView.delegate = self。然后您可以使用委托进行演示。
  • 如果您仍在寻找解决方案,我有一个答案,您可以将第一个父视图控制器获取到任何视图,以便我发布它。

标签: ios swift uiviewcontroller uicollectionview uicollectionviewcell


【解决方案1】:

我通过在我的自定义UICollectionViewCell 中创建一个协议并将这些事件委托给UIViewController 来做到这一点,就像这样

在你的MyCollectionViewCell

protocol MyCollectionViewCellDelegate: class {
    func didLongPressCell()
}

class MyCollectionViewCell:UICollectionViewCell {

    weak var delegate:MyCollectionViewCellDelegate?

    func longPressAction() {
        if let del = self.delegate {
            del.didLongPressCell
        }
    }

}

然后回到你的MyViewController

class MyViewController:UIViewController, MyCollectionViewCellDelegate {

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! MyCollectionViewCell
        cell.delegate = self
        return cell
    }

    func didLongPressCell() {
        // do what you want with the event from the cell here
    }

}

要记住的重要一点是为每个单元格设置委托

cell.delegate = self

并在您想要接收事件的视图控制器中采用您的新协议

class MyViewController:UIViewController, MyCollectionViewCellDelegate

我没有测试过这段代码,我不确定在每个单元格中存储对 viewController 的引用的最佳实践,但我做了一些非常相似的事情,让我知道你的进展情况。 em>


编辑:如果您已将 UICollectionView 子类化,则将其传递给视图控制器,以便您可以像这样使用它。

您的 MyViewController 现在看起来像这样

class MyViewController:UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let collectionView = MyCollectionView()
        collectionView.viewController = self
        self.view.addSubview(collectionView)
    }

}

还有你的自定义集合视图MyCollectionView

class MyCollectionView:UICollectionView, MyCollectionViewCellDelegate {

    weak var viewController:UIViewController?

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! MyCollectionViewCell
        cell.delegate = self
        return cell
    }

    func didLongPressCell() {
        if let vc = self.viewController {
            // make use of the reference to the view controller here
        }
    }

}

UICollectionViewCell 与以前相同

【讨论】:

  • 我会让委托变弱以避免引用循环。
  • @nils 我已经更新了答案 - 只是快速搜索了一下,我当前的项目有 39 个可能需要更新的代表:|
  • 谢谢!这看起来不错,但问题是在 UICollectionView 而不是在 UIViewController 中调用了 cellForItemAtIndexPath 函数。我不太了解协议,有没有办法从 UICollectionView 到 UIViewController 做你上面所做的事情?
  • @PelayoMartinez 您将答案标记为已接受,这是否意味着您想通了?或者你还需要帮助吗?如果您需要帮助,我会在chat
  • @Wez 我认为我仍然需要一些帮助。我也许可以做一些其他的事情来规避它,但我认为找到一种从不是视图控制器的类中呈现视图控制器的方法会很好。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多