滚动时 UITableView 复选标记消失

Posted

技术标签:

【中文标题】滚动时 UITableView 复选标记消失【英文标题】:UITableView Checkmarks disappear when scrolling 【发布时间】:2015-03-11 04:46:26 【问题描述】:

我必须在 tableView 上做复选标记,但是如果我正在滚动并且一个复选标记的单元格不可见并且我向后滚动复选标记消失了。

在运行这段代码时

var boolArray = [Bool]()

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)      




        var cell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!


        if cell.accessoryType == UITableViewCellAccessoryType.Checkmark 

            cell.accessoryType = UITableViewCellAccessoryType.None

            boolArray[indexPath.row] = false


        
        else
        

            cell.accessoryType = UITableViewCellAccessoryType.Checkmark

            boolArray[indexPath.row] = true

        

    println(boolArray)



 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->    UITableViewCell

    boolArray.append(false)
        var view = UITableViewCell(style: UITableViewCellStyle.Default,    reuseIdentifier: "CellTable")


        return view


稍微滚动和勾选后,打印出来的数组就这么大了……

[真、假、真、真、真、假、假、假、假、假、假、假、假、假、假、假、假、假、假、假、假、假、假]

【问题讨论】:

【参考方案1】:

NSMutableIndexSet 是用于跟踪选择状态的更好对象。

您还需要在为 indexPath 返回单元格时检查选择状态

var selectedCells = NSMutableIndexSet()

func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath)      

    var accessory=UITableViewCellAccessoryType.none

    if (selectedCells.containsIndex(indexPath.row) 
       selectedCells.removeIndex(indexPath.row)
    
    else 
       selectedCells.addIndex(indexPath.row)
       accessory=.checkmark
    

    if let cell = tableView.cellForRowAtIndexPath(indexPath) 

        cell.accessoryType = accessory
    



func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) ->    UITableViewCell

    var cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier:"CellTable")

     var accessory=UITableViewCellAccessoryType.none

     if (selectedCells.containsIndex(indexPath.row) 
         accessory = .checkmark
     

     view.accessoryType=accessory

        return view

【讨论】:

【参考方案2】:

创建一个元组数组来存储行和节值:

var selectedCells:[(row: Int, section: Int)] = []

在您的cellForRowAtIndexPath 中,检查您是否有任何selectedCellValues。如果是这样,请为该单元格添加一个accessoryType 并跳出循环,

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

    let cell = tableView.dequeueReusableCellWithIdentifier("SettingsCell", forIndexPath: indexPath) as SettingsCustomCell

    var rowNums:NSNumber = indexPath.row
    var sectionNums:NSNumber = indexPath.section

    var selectedRow:Int
    var selectedSection:Int

    if(selectedCells.count > 0)
        for tuple in selectedCells

            selectedRow = tuple.row
            selectedSection = tuple.section

            if(selectedRow == rowNums && selectedSection == sectionNums)
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
                break
            else
                cell.accessoryType = UITableViewCellAccessoryType.None
            
        
    else
        cell.accessoryType = UITableViewCellAccessoryType.None
    

    var keyValue = listOfSectionTitles[indexPath.section]
    var items: [NSString] = dictionaryOfCellTitles.objectForKey(keyValue) as [NSString]

    cell.textLabel?.text = items[indexPath.row]
    return cell

didSelecteRowAtIndexPath 中处理selectedcellvalues

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 

    let cell = tableView.cellForRowAtIndexPath(indexPath)

    if(cell?.accessoryType == UITableViewCellAccessoryType.None)
        cell?.accessoryType = UITableViewCellAccessoryType.Checkmark
        selectedCells.append(row:indexPath.row, section:indexPath.section)
    else
        var rowToDelete = indexPath.row
        var sectionToDelete = indexPath.section

        for var i=0; i < selectedCells.count; i++
        
            if(rowToDelete == selectedCells[i].row && sectionToDelete == selectedCells[i].section)
                selectedCells.removeAtIndex(i)
                cell?.accessoryType = UITableViewCellAccessoryType.None
            
        
    
    tableView.deselectRowAtIndexPath(indexPath, animated: true)

【讨论】:

【参考方案3】:

当您执行boolArray.append(false) 时,您的错误在cellForRowAtIndexPath。每次绘制单元格时都会调用cellForrRowAtIndexPath:即使之前已经绘制过。如果indexPath.row 大于boolArray 的长度,则可能的解决方法是仅附加 false,否则它是您的“模型”,您只需检查它。

【讨论】:

【参考方案4】:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->    UITableViewCell
var cell : UITableViewCell = .........
if(boolArray[indexPath.row)
    cell.accessoryType = UITableViewCellAccessoryType.Checkmark
 else 
    cell.accessoryType = UITableViewCellAccessoryType.None


试试这个代码。

【讨论】:

你忘记了 indexPath.row 之后的 ]【参考方案5】:
 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->    UITableViewCell

重用单元格,正如您从代码中看到的那样。您需要保留所选单元格的状态,并在var view = UITableViewCell ... 之后分配附件视图状态

【讨论】:

以上是关于滚动时 UITableView 复选标记消失的主要内容,如果未能解决你的问题,请参考以下文章

tableview 编辑模式单元格选择复选标记在滚动时消失

滚动会弄乱 UITableView 中的自定义单元格

当我向下滚动表格视图时,隐藏单元格的复选标记消失了

隐藏 UITableViewCell 时,accessoryType 复选标记消失

保存 UITableviewcell accessoryView 的状态

在滚动 UITableViewCell 添加按钮图像问题