【发布时间】:2015-06-12 00:42:48
【问题描述】:
我有一个集合视图,当一个单元格被选中时,它会显示一个弹出视图,显示有关该单元格的更多信息。
我希望允许用户单击另一个单元格,然后将弹出视图更改为显示该单元格的信息,而无需关闭弹出框。如果用户要单击父视图上不是单元格的某个位置,则弹出框应该关闭。但是,我希望用户仍然能够在不关闭弹出框的情况下滚动集合视图。
如何做到这一点?
【问题讨论】:
标签: ios swift uicollectionview uipopover
我有一个集合视图,当一个单元格被选中时,它会显示一个弹出视图,显示有关该单元格的更多信息。
我希望允许用户单击另一个单元格,然后将弹出视图更改为显示该单元格的信息,而无需关闭弹出框。如果用户要单击父视图上不是单元格的某个位置,则弹出框应该关闭。但是,我希望用户仍然能够在不关闭弹出框的情况下滚动集合视图。
如何做到这一点?
【问题讨论】:
标签: ios swift uicollectionview uipopover
您正在寻找的是弹出框的passthroughViews 属性。
但是,如果您通过点击单元格来打开弹出框,我看不出滚动 collectionView 会有什么意义。你不打开弹出窗口,箭头指向你的单元格吗?滚动视图将使呈现单元格移开...
【讨论】:
您可以使用 UIViewController 'modalInPopover' 的属性来启用弹出框边界之外的触摸。只需在您使用弹出控制器呈现的视图控制器中编写下面给出的行。
self.modalInPopover = false;
self 是一种 UIViewController。
我已经附上了相同的截图。
很快,这条线将保持不变
self.modalInPopover = false
【讨论】:
passthroughView 属性可以在您希望在某些特定视图中启用触摸时使用。
根据苹果:
当弹出框处于活动状态时,与其他视图的交互通常会被禁用,直到弹出框被关闭。将视图数组分配给此属性允许弹出框外部的点击由相应的视图处理。
那么您可以通过以下方式使用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 的形式显示。
我想指出答案中的一些观察结果:
我设置了对 PopoverViewController 类的引用,以使其在整个生命周期中保持不变,并在它仍处于打开状态时传递数据。
var t = self.popoverViewController!.view 行是必需的,因为如果不是 PopoverViewController 中的 @IBOutlet 直到它出现才被初始化,那么可能有其他方法可以做到这一点。
我在屏幕中间展示了弹出框来处理多个单元格中的点击并测试它的滚动,你可以在任何你想要的位置显示它。
在打开弹出框时允许的视图中,我设置了self.view,但是这样你需要自己关闭它,因为当你在视图中点击时它永远不会被关闭,你可以放任何你想要的视图。
您对解决方案有任何问题,我可以在 Github 上分享项目。
希望对你有帮助
【讨论】: