呈现弹出视图时,如何让用户 select 单元格出现在父集合视图中?

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

I have a collection view and when a cell is selected it presents a popover view showing more information about that cell.

我想允许用户单击另一个单元格,然后让弹出窗口视图更改为显示该单元格的信息,而无需关闭弹出窗口。如果用户要单击父视图上不是单元格的某个位置,则弹出窗口应该关闭。但是,我希望用户仍然能够在不关闭弹出窗口的情况下滚动集合视图。

如何做到?

你要找的是popover的passthroughViews属性

但是,如果您通过点击单元格打开弹出框,我看不出滚动 collectionView 有什么意义。你不打开弹出窗口,箭头指向你的单元格吗?滚动视图将使呈现单元格移开...

您可以使用 UIViewController 属性 'modalInPopover' 启用弹出框边界外的触摸。只需在您使用弹出窗口控制器呈现的视图控制器中写入下面给出的行。

self.modalInPopover = false;

其中 self 是一种 UIViewController。

我已附上相同的屏幕截图。

在 swift 中,该行将保持不变

self.modalInPopover = false

根据 Apple 的说法:

When a popover is active, interactions with other views are normally disabled until the popover is dismissed. Assigning an array of views to this property allows taps outside of the popover to be handled by the corresponding views.

然后您可以按以下方式使用 passthroughViews :

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

上面的代码是 CollectionViewController 来处理 UICollectionViewController 及其所有委托。

CollectionViewCell

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

内部只有 UILabel 的自定义单元格。

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.
   }   
}

最后 PopoverViewController.Popover 的形式显示。

我想指出回答中的一些观察结果:

  • 我设置了对 class PopoverViewController 的引用,以保持它的生命周期并在它保持打开状态时传递数据。

  • var t = self.popoverViewController!.view 是必要的,因为如果 PopoverViewController 中的 @IBOutlet 在出现之前不会初始化,可能还有其他方法可以做到这一点.

  • 我在屏幕中间展示了弹出窗口来处理多个单元格中的点击并测试它的滚动,你可以在任何你想要的位置显示它。

  • 在打开弹出窗口时允许的视图中,我设置了self.view,但是这样你需要自己关闭它,因为当你打开它时它永远不会被关闭在视图中点击,您可以放置​​任何您想要的视图。

如果您对解决方案有任何疑问,我可以在 Github 上分享项目。

希望对你有所帮助