Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

ios - Access a UICollectionView's parent UIViewController

My question is fairly straightforward. I have a UIViewController containing a UICollectionView. In initialising my cells, I add a gesture recogniser to each of them so that when you tap and hold it calls a function with a selector.

This function then creates a UIAlertController which I want to present. (Basically, you hold a cell, it asks you if you want to delete it and if you say yes it eliminates it from the CollectionView)

The problem is that I can't present a UIAlertController from my UICollectionView because it isn't a ViewController.

I want to programmatically get the UIViewController that contains the UICollectionView to present this alert from a function that is inside the UICollectionView implementation.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I do this by making a protocol in my custom UICollectionViewCell and delegate these events back to the UIViewController, something like this

In your MyCollectionViewCell

protocol MyCollectionViewCellDelegate: class {
    func didLongPressCell()
}

class MyCollectionViewCell:UICollectionViewCell {

    weak var delegate:MyCollectionViewCellDelegate?

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

}

Then back in your 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
    }

}

The important bits to remember are to set the delegate for each cell

cell.delegate = self

And adopt your new protocol in the view controller that you want to receive the events in

class MyViewController:UIViewController, MyCollectionViewCellDelegate

I have not tested this code and I'm not sure on best practice of storing references to the viewController in every cell like this, but i do something very similar, let me know how you get on.


Edit: if you have subclassed your UICollectionView then pass it a reference to the view controller so that you can use it like so.

Your MyViewController would now look like this

class MyViewController:UIViewController {

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

}

And your custom collection view 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
        }
    }

}

The UICollectionViewCell would be the same as before


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...