我有一个带有两个集合视图的简单屏幕。我想要的是,当我在第一个简历中选择一个项目时,我想显示一个选择标识并在第二个简历中多次显示此项目,如以下屏幕截图所示(忽略图像中的透明度):与UICollectionView单元格选择相关的问题使其布局无效时
这里是我的代码(这是一个有点长,但它是非常简单):
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
@IBOutlet weak var cv1: UICollectionView!
@IBOutlet weak var cv2: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
cv1.dataSource = self
cv1.delegate = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let layout = cv1.collectionViewLayout as! UICollectionViewFlowLayout
var size = layout.itemSize
size.width = cv1.bounds.width/CGFloat(items.count)
layout.itemSize = size
layout.invalidateLayout()
cv1.reloadData()
}
let items = ["A", "B", "C", "D", "E", "F", "G", "E", "H", "I"]
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! CollectionViewCell
cell.setText(collectionView == cv1 ? items[indexPath.row] : items[currentSelection])
return cell
}
var currentSelection = -1
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if currentSelection != -1 {
let oldCell = collectionView.cellForItemAtIndexPath(NSIndexPath(forRow: currentSelection, inSection: 0)) as? CollectionViewCell
oldCell?.makeSelect(false)
}
var shouldSelect = true
if indexPath.row != currentSelection {
currentSelection = indexPath.row
}
else {
currentSelection = -1
shouldSelect = false
}
let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CollectionViewCell
cell?.makeSelect(shouldSelect)
// if you comment the block of code bellow the selection works fine
if collectionView == cv1 {
if shouldSelect {
cv2.dataSource = self
cv2.delegate = self
cv2.reloadData()
cv2.alpha = 1
}
else {
cv2.dataSource = nil
cv2.delegate = nil
cv2.alpha = 0
}
}
}
}
class CollectionViewCell: UICollectionViewCell {
@IBOutlet weak var label: UILabel!
func setText(str: String) {
label.text = str
}
func makeSelect(selected: Bool) {
contentView.backgroundColor = selected ? UIColor.yellowColor() : UIColor.clearColor()
}
}
的问题是,当你运行该项目,并选择以字母d的细胞,会发生什么这个:
如果您viewDidLayoutSubviews
删除以下行的方法中,一切工作正常:
cv1.reloadData()
然而,在我真正的项目,我需要调用reloadData()
功能在这个地方。
我认为问题不在于此调用,因为如果您评论代码中标记的块,出现第二个集合视图的块,您将看到第一个集合视图中的选择无法正常工作致电reloadData()
。如果对单元使用不同的重用标识符,也会出现此问题。
我的问题是:这是怎么回事?
你真的需要重新加载“viewDidLayoutSubviews”中的集合视图?你能否只是使布局失效? – almas
@almas问题是,在我遇到这个问题的真实项目中,我对某些单元格应用了透明度。它在iPhone中可以正常工作,但在iPad中不起作用,我设法使其工作的唯一方法是调用reloadData函数。我已经解决了iPad中透明度相关的问题,但我想知道为什么会出现这种情况。 –
我认为在这种情况下,您需要先解决您的透明度问题。重新加载“viewDidLayoutSubviews”中的数据没有意义。如果您绝对必须这样做,那么您只需记住所选单元格的索引,重新加载数据,然后再次以编程方式选择该单元格。 – almas