我们假设您在UICollectionView的单元格(来自图像名称数组)中设置了一堆图像视图,并在设置项目时默认设置为alpha 0.5。
然后在didSelectItemAtIndexPath func中将图像视图的alpha设置为1.0,因此当用户点击时它变为alpha 1。
当用户点击一个单元格时,这种方法有效,但如果用户滚动则不会保留,因为该单元格正在被其他级别的UI重用。
结果是另一个单元格(滚动时)变为alpha 1.0并且您选择的原始单元格将恢复为之前的alpha 0.5外观。
我知道这一切都是为了让设备上的功能更高效,但我仍然没有弄清楚如何让它在所选项目持续存在的情况下正常工作。
ANSWER
Apple 为可用于更改背景颜色,阴影效果或轮廓等的单元格提供selectedBackgroundView。它们还允许您使用&#34在单元格内使用图像;默认"并且"突出显示"状态。
这两种方法都会在选择正确的情况下持续存在。
但是,如果您希望使用属性或不同的元素之一来指示您选择的状态,则必须使用包含对当前所选项的引用的单独数据模型元素。然后,当用户选择一个项目时,您必须重新加载视图控制器数据,从而导致所有单元格都被重新绘制,并将所选状态应用于其中一个单元格。
以下是我用来解决问题的代码的主旨,感谢Matt的耐心和帮助。
所有这些都可以位于主UICollectionView Controller类文件中,或者如果您需要在项目的其他位置使用它,则数据数组和结构可以位于自己的swift文件中。
数据和数据模型:
let imagesArray=["image1", "image2", "image3", ...]
struct Model {
var imageName : String
var selectedState : Bool
init(imageName : String, selectedState : Bool = false){
self.imageName = imageName
self.selectedState = selectedState
}
}
UICollectionView控制器的代码
// create an instance of the data model for images and their status
var model = [Model]()
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// build out a data model instance based on the images array
for i in 0..<imagesArray.count {
model.append(Model(imageName: imagesArray[i]))
// the initial selectedState for all items is false unless otherwise set
}
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imagesArray.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
// when the collectionview is loaded or reloaded...
let cell:myCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! myCollectionViewCell
// populate cells inside the collectionview with images
cell.imageView.image = UIImage(named: model[indexPath.item].imageName)
// set the currently selected cell (if one exists) to show its indicator styling
if(model[indexPath.item].selectedState == true){
cell.imageView.alpha = 1.0
} else {
cell.imageView.alpha = 0.5
}
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
// when a cell is tapped...
// reset all the selectedStates to false in the data model
for i in 0..<imagesArray.count {
model[i].selectedState = false
}
// set the selectedState for the tapped item to true in the data model
model[indexPath.item].selectedState = true
// refresh the collectionView (triggering cellForItemAtIndexPath above)
self.collectionView.reloadData()
}
答案 0 :(得分:2)
但是如果用户滚动它并不会持续存在,因为UI会在其他某个级别上重复使用该单元格
因为你做错了。在didSelect
中,不对任何单元格进行更改。而是对基础数据模型进行更改,并重新加载集合视图。这完全取决于您的数据模型和cellForItemAtIndexPath:
的实施情况;这就是单元格和插槽(项目和部分)相遇的地方。
这是一个简单的例子。我们只有一个部分,因此我们的模型可以是模型对象的数组。我将假设100行。我们的模型对象只包含要进入此项目的图像名称,以及是否淡化此图像视图的知识:
struct Model {
var imageName : String
var fade : Bool
}
var model = [Model]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<100 {
// ... configure a Model object and append it to the array
}
}
override func collectionView(
collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return 100
}
现在,选择项目时会发生什么?我会假设单一选择。因此,在我们的模型中,该项目和其他项目都不应标记为淡入淡出。然后我们重新加载数据:
override func collectionView(cv: UICollectionView,
didSelectItemAtIndexPath indexPath: NSIndexPath) {
for i in 0..<100 {model[i].fade = false}
model[indexPath.item].fade = true
cv.reloadData()
}
所有实际工作都在cellForItemAtIndexPath:
完成。这项工作基于模型上的 :
override func collectionView(cv: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let c = self.collectionView!.dequeueReusableCellWithReuseIdentifier(
"Cell", forIndexPath: indexPath) as! MyCell
let model = self.model[indexPath.item]
c.iv.image = UIImage(named:model.imageName)
c.iv.alpha = model.fade ? 0.5 : 1.0
return c
}
答案 1 :(得分:0)
你的逻辑不正确。 didSelectItemAtIndexPath 用于在选择单元格时触发某些内容。所有这个功能应该包含:
let cell:stkCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! stkCollectionViewCell
cell.imageView.alpha = 1.0
selectedIndex = indexPath.item
然后在 cellForItemAtIndexPath 函数中,您应该具有设置单元格的逻辑,因为这是单元格重用的位置。所以这个逻辑应该在那里:
if (indexPath.item == selectedIndex){
print(selectedIndex)
cell.imageView.alpha = 1.0
}
else {
cell.imageView.alpha = 0.5
}