我有一个UICollectionView
,其中我只希望1个单元格处于活动状态。活跃的意思是:已经点击的最后一个单元格(或者收集视图放置时的第一个单元格)。当用户单击非活动单元格时,我想将旧的活动单元格重置为非活动单元格。我这样做有困难。这是因为visibleCells
是集合视图的属性,它只返回屏幕上的单元格而不返回内存中的单元格。这是我目前查找活动单元格并将状态重置为非活动状态的方法。
这种情况可能发生,导致多个活动单元格:用户稍微向下滚动,以便当前活动单元格不再可见,点击随机单元格并向上滚动。问题是旧的活动单元格保留在内存中,尽管它不可见:cellForItemAt(_:)
不会被调用该单元格。坏消息是,visibleCells也找不到旧的活动单元格。我该怎么找到它?函数willDisplay cell
也不起作用。
可以将示例项目直接克隆到xCode:https://github.com/Jasperav/CollectionViewActiveIndex。
这是示例项目中的代码:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var collectionView: CollectionView!
static var activeIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
collectionView.go()
}
}
class Cell: UICollectionViewCell {
@IBOutlet weak var button: MyButton!
}
class CollectionView: UICollectionView, UICollectionViewDelegate, UICollectionViewDataSource {
func go() {
delegate = self
dataSource = self
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 500
}
internal func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! Cell
if indexPath.row == ViewController.activeIndex {
cell.button.setTitle("active", for: .normal)
} else {
cell.button.setTitle("not active", for: .normal)
}
cell.button.addTarget(self, action: #selector(touchUpInside(_:)), for: .touchUpInside)
return cell
}
@objc private func touchUpInside(_ sender: UIButton){
let hitPoint = sender.convert(CGPoint.zero, to: self)
guard let indexPath = indexPathForItem(at: hitPoint), let cell = cellForItem(at: indexPath) as? Cell else { return }
// This is the problem. It does not finds the current active cell
// if it is just out of bounds. Because it is in memory, cellForItemAt: does not gets called
if let oldCell = (visibleCells as! [Cell]).first(where: { $0.button.titleLabel!.text == "active" }) {
oldCell.button.setTitle("not active", for: .normal)
}
cell.button.setTitle("active", for: .normal)
ViewController.activeIndex = indexPath.row
}
}
答案 0 :(得分:1)
要从这个小故障中恢复,您可以尝试cellForRowAt
cell.button.tag = indexPath.row
单击按钮时
ViewController.activeIndex = sender.tag
self.reloadData()
答案 1 :(得分:0)
您可以使用isSelected
的{{1}}属性。如果选中,则可以为单元格设置活动布局。选择机制默认在UIColectionViewCell
中实现。如果要选择/激活多个单元格,可以将属性UIColectionViewCell
设置为true。
基本上这种方法看起来像这样:
allowsMultipleSelection