When you present a popover view, how can I let the user select a cell in the parent collection view?

I have a collection view, and when a cell is selected, it is a popover view displaying more information about this cell.

I would like the user to click on another cell and then change the appearance of the popover to show this cell information without closing the popover. If the user needs to click somewhere on the parent view, which is not a cell, then the popsor should close. But I would like the user to still be able to scroll through the collection view without closing the popover.

How can I do that?

+8
ios swift uicollectionview uipopover
source share
3 answers

According to Apple:

When a popover is active, interaction with other views is usually disabled until the popover is fired. Assigning an array of views to this property allows you to handle taps outside the popover with the corresponding views.

Then you can use passthroughViews as follows:

CollectionViewController

 import UIKit let reuseIdentifier = "Cell" class CollectionViewController: UICollectionViewController { var popoverViewController : PopoverViewController? override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { //#warning Incomplete method implementation -- Return the number of sections return 1 } override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { //#warning Incomplete method implementation -- Return the number of items in the section return 15 } override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CollectionViewCell cell.labelInfo.text = "Cell \(indexPath.row)" return cell } override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { println("tapped") if let popover = self.popoverViewController { var cell = self.collectionView!.cellForItemAtIndexPath(indexPath) as! CollectionViewCell popover.labelPop.text = cell.labelInfo.text } else { self.popoverViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PopoverViewController") as? PopoverViewController var cell = self.collectionView!.cellForItemAtIndexPath(indexPath) as! CollectionViewCell var t = self.popoverViewController!.view self.popoverViewController!.labelPop.text = cell.labelInfo.text self.popoverViewController!.modalPresentationStyle = .Popover var popover = self.popoverViewController!.popoverPresentationController popover?.passthroughViews = [self.view] popover?.sourceRect = CGRect(x: 250, y: 500, width: 0, height: 0) self.popoverViewController!.preferredContentSize = CGSizeMake(250, 419) popover!.sourceView = self.view self.presentViewController(self.popoverViewController!, animated: true, completion: nil) } } } 

The above code is a CollectionViewController to handle the UICollectionViewController and all its delegates.

CollectionViewCell

 class CollectionViewCell: UICollectionViewCell { @IBOutlet weak var labelInfo: UILabel! } 

Custom cell with only UILabel inside.

Popoverviewcontroller

 class PopoverViewController: UIViewController { @IBOutlet var labelPop: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } 

And finally, a PopoverViewController to display in .Popover form.

There are a few comments in the answer:

  • I set up a reference to the PopoverViewController class to save it throughout the life cycle and pass it when it is still open.

  • The string var t = self.popoverViewController!.view necessary because if there was no @IBOutlet inside the PopoverViewController there was no init before it was presented, there could be other ways to do this.

  • I present a popover in the middle of the screen to handle the tap in several cells and check its scrolling as well, you can display it in any position you want.

  • In the views that are allowed when opening popover, I set self.view , but in this way you need to cancel it for yourself, because it never deviates, when you make taps in the view, you can put any view you want instead .

Any problems you encounter with a solution, I can share it with a project on Github.

I hope this helps you

+11
source share

What you are looking for is the passthroughViews popover property.

However, if you open a popover as a result of clicking on a cell, I do not see how the scroll of the View collection will look. Don't you open a popover with an arrow pointing to your camera? Scrolling the view will make the display cell move away ...

+5
source share

You can use the UIViewController 'modalInPopover' property to enable bindings outside the popover border. Just write the line below in your view controller, which you represent using the popover controller.

 self.modalInPopover = false; 

where self is a UIViewController.

I added a screenshot for the same.

enter image description here

In the fast line, the line will remain the same.

 self.modalInPopover = false 

enter image description here

+3
source share

All Articles