我知道這個問題已被問了很多次。UICollectionView單元重用導致問題,即使採取步驟後
我使用的定製單元格有UICollectionView
,它們有幾個屬性,最重要的是UISwitch
的數組和UILabel
的數組。你可以猜到,當我滾動時,標籤重疊,開關改變狀態。我已經實施了UICollectionViewCell
prepareForReuse
的方法,其中我清空這些數組並重置主標籤文本。
我試圖結合來自不同答案的解決方案,我已經達到了我的標籤保存點,但我的開關在單元格中的狀態不是。我的下一步是在刪除開關之前創建一個數組來保存狀態,然後將新創建的開關的on屬性設置爲索引處的該數組的值。這是有效的,直到我非常快地滾動並切換先前未被選擇的單元(或未選中)。這對我來說是一個巨大的問題。
這是我的CollectionView cellForItemAtIndexPath
方法:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("pitanjeCell", forIndexPath: indexPath) as! PitanjeCell
// remove views previously created and create array to preserve the state of switches
var selectedSwitches: [Bool] = []
for item: UIView in cell.contentView.subviews {
if (item.isKindOfClass(UILabel) && !item.isEqual(cell.tekstPitanjaLabel)){
item.removeFromSuperview()
}
if (item.isKindOfClass(UISwitch)){
selectedSwitches.append((item as! UISwitch).on)
item.removeFromSuperview()
}
}
// get relevant data needed to place cells programmatically
cell.tekstPitanjaLabel.text = _pitanja[indexPath.row].getText()
let numberOfLines: CGFloat = CGFloat(cell.tekstPitanjaLabel.numberOfLines)
cell.setOdgovori(_pitanja[indexPath.row].getOdgovori() as! [Odgovor])
var currIndex: CGFloat = 1
let floatCount: CGFloat = CGFloat(_pitanja.count)
let switchConstant: CGFloat = 0.8
let switchWidth: CGFloat = cell.frame.size.width * 0.18
let heightConstant: CGFloat = (cell.frame.size.height/(floatCount + 2) + (numberOfLines * 4))
let labelWidth: CGFloat = cell.frame.size.width * 0.9
for item in _pitanja[indexPath.row].getOdgovori() {
// create a switch
let odgovorSwitch: UISwitch = UISwitch(frame: CGRectMake((self.view.frame.size.width - (switchWidth * 2)), currIndex * heightConstant , switchWidth, 10))
odgovorSwitch.transform = CGAffineTransformMakeScale(switchConstant, switchConstant)
let switchValue: Bool = selectedSwitches.count > 0 ? selectedSwitches[Int(currIndex) - 1] : false
odgovorSwitch.setOn(switchValue, animated: false)
// cast current item to relevant class
let obj: Odgovor = item as! Odgovor
// create a label
let odgovorLabel: UILabel = UILabel(frame: CGRectMake((self.view.frame.size.width/12), currIndex * heightConstant , labelWidth, 20))
odgovorLabel.text = obj.getText();
odgovorLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
odgovorLabel.font = UIFont(name: (odgovorLabel.font?.fontName)!, size: 15)
// add to cell
cell.addSwitch(odgovorSwitch)
cell.addLabel(odgovorLabel)
currIndex++
}
return cell
}
我的自定義單元格也實現方法addSwitch
和addLabel
該元素添加到contentView
作爲subview
。
有什麼辦法可以在滾動時始終保持開關狀態?
編輯:按照@Victor格萊爾的建議,我創建了一個bydimensional陣列像這樣:
var _switchStates: [[Bool]]!
我初始化這樣的:
let odgovori: Int = _pitanja[0].getOdgovori().count
_switchStates = [[Bool]](count: _pitanja.count, repeatedValue: [Bool](count: odgovori, repeatedValue: false))
我改變了我的方法是這樣的:
for item: UIView in cell.contentView.subviews {
if (item.isKindOfClass(UILabel) && !item.isEqual(cell.tekstPitanjaLabel)){
item.removeFromSuperview()
}
if (item.isKindOfClass(UISwitch)){
_switchStates[indexPath.row][current] = (item as! UISwitch).on
current++
selectedSwitches.append((item as! UISwitch).on)
item.removeFromSuperview()
}
}
而最後:
let switchValue: Bool = _switchStates.count > 0 ? _switchStates[indexPath.row][Int(currIndex) - 1] : false
請將您的答案標記爲解決方案。 :) –