标题可能有点难以理解,但这种情况可能会帮助你。
我正在编写一个多图像选择器。假设限制为 3 张图片,当用户选择了 3 张后,所有其他图像将具有 alpha = 0.3
以指示该图像不可选择。 (一直向下滚动以查看演示)
首先,这是我的代码:
PickerPhotoCell(自定义 Collection View 单元格):
class PickerPhotoCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
var selectable: Bool {
didSet {
self.alpha = selectable ? 1 : 0.3
}
}
}
照片选择器 View Controller :
class PhotoPickerViewController: UICollectionViewController {
...
var photos: [PHAsset]() // Holds all photo assets
var selected: [PHAsset]() // Holds all selected photos
var limit: Int = 3
override func viewDidLoad() {
super.viewDidLoad()
// Suppose I have a func that grabs all photos from photo library
photos = grabAllPhotos()
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell ...
let asset = photos[indexPath.row]
...
// An image is selectable if:
// 1. It's already selected, then user can deselect it, or
// 2. Number of selected images are < limit
cell.selectable = cell.isSelected || selected.count < limit
return cell
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! PickerPhotoCell
if cell.isSelected {
// Remove the corresponding PHAsset in 'selected' array
} else {
// Append the corresponding PhAsset to 'selected' array
}
// Since an image is selected/deselected, I need to update
// which images are selectable/unselectable now
for visibleCell in collectionView.visibleCells {
let visiblePhoto = visibleCell as! PickerPhotoCell
visiblePhoto.selectable = visiblePhoto.isSelected || selected.count < limit
}
}
}
这几乎完美,除了一件事,看看 GIF:
问题是
在我选择了 3 张照片之后,所有其他可见的照片都有 alpha = 0.3
,但是当我再向下滚动一点时,有些照片仍然有 alpha = 1
。我知道为什么会这样——因为它们在屏幕外,调用 collectionView.visibleCells
不会影响它们,而且与其他不存在的单元格不同,它们确实存在,即使它们在屏幕外。所以我想知道如何访问它们并因此使它们不可选择?
最佳答案
问题是您试图将状态存储在单元格本身中,方法是:if cell.isSelected...
。 Collection View 中没有屏幕外的单元格,它始终重复使用单元格,实际上您应该在 prepareForReuse
方法中重置单元格的状态。这意味着您需要将数据存储在 UICollectionViewCell 之外。
您可以做的是将选定的 IndexPath
存储在 View Controller 的属性中,并使用该数据来标记您的单元格是否选定
。
伪代码:
class MyViewController {
var selectedIndexes = [IndexPath]()
func cellForItem(indexPath) {
cell.isSelected = selectedIndexes.contains(indexPath)
}
func didSelectCell(indexPath) {
if selectedIndexes.contains(indexPath) {
selectedIndexes.remove(indexPath)
} else if selectedIndexes.count < limiit {
selectedIndexes.append(indexPath)
}
}
}
关于ios - 如何在 Swift 中访问 UICollectionView 中屏幕外但现有的单元格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49745466/