UITableViewCell checkmark to be toggled on and off

2020-01-27 12:03发布

I'm working on a tableview

I want to be able to tap on each cell and when tapped, it displays a checkmark on the cell

Now I have some code that makes this work:

// checkmarks when tapped

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let section = indexPath.section
    let numberOfRows = tableView.numberOfRowsInSection(section)
    for row in 0..<numberOfRows {
        if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: row, inSection: section)) {
            cell.accessoryType = row == indexPath.row ? .Checkmark : .None
        }
    }
}

but this code only selects 1 cell inside a section (I have 5 sections)

I need it to select any cell anywhere

Also when I drag my screen up and down I lose by checkmark

viewcontroller.swift

class ViewController: UIViewController, UITableViewDataSource {                        //class and subclass                  |)
//---------------------------------------------------------------------------------------------------------------------------/
    // Variable and constant, also IBAOutlet

    let section1 =
       ["this is used",
        "this is used to test",
        "this is used to test the lenght",
        "this is used to test the lenght of the text",
        "this is used to test the lenght of the text",
        "this is used to test the lenght of the text",
        "this is used to test the lenght of the text",
        "this is used to test the lenght of the text",
        "this is used to test the lenght of the text",]
    let section2 =
       ["this is used to test the lenght of the text"]
    let section3 =
       ["this is",
        "this is ",]


    @IBOutlet weak var scoreshow: UILabel!
    @IBOutlet weak var reset: UIButton!
    @IBOutlet weak var tableView: UITableView!

// --------------------------------------------------------------------------------------

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()
    }
//----------------------------------------------------------------------------------------
    // checkmarks when tapped

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    {
        if let cell = tableView.cellForRowAtIndexPath(indexPath) {
            if cell.accessoryType == .Checkmark
            {
                cell.accessoryType = .None
            }
            else
            {
                cell.accessoryType = .Checkmark
            }
        }    
    }
//----------------------------------------------------------------------------------------
    //number of sections for the table

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 5
    }
//----------------------------------------------------------------------------------------
    //Calculate the amount of rows

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return self.section1.count;
    }
//----------------------------------------------------------------------------------------
    //Cells text label and config

    func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell:UITableViewCell = UITableViewCell(style:UITableViewCellStyle.Default, reuseIdentifier:"cell")
        cell.textLabel!.text = section1[indexPath.row]
        cell.textLabel!.numberOfLines = 0

        return cell
    }

//----------------------------------------------------------------------------------------

    @IBAction func resetswitch(sender: UIButton) {




    }
//----------------------------------------------------------------------------------------

}

11条回答
We Are One
2楼-- · 2020-01-27 12:09

Swift 4.0, all together now:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var yourData = ["Cool","Sweet","Awesome"]

var checked = [Bool]()

override func viewDidLoad() {
    super.viewDidLoad()
    checked = Array(repeating: false, count: yourData.count)
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return searchData.count
}
func tableView(_ tableView: UITableView, cellForRowAt IndexPath: IndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell

    //configure you cell here.
    if checked[IndexPath.row] == false{
        cell.accessoryType = .none
    } else if checked[IndexPath.row] {
        cell.accessoryType = .checkmark
    }

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)

    if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
        if cell.accessoryType == .checkmark {
            cell.accessoryType = .none
            checked[indexPath.row] = false
        } else {
            cell.accessoryType = .checkmark
            checked[indexPath.row] = true
        }
    }
}

}

查看更多
小情绪 Triste *
3楼-- · 2020-01-27 12:11

Try this:

var checked = [Bool]() // Have an array equal to the number of cells in your table


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell

    //configure you cell here.
    if !checked[indexPath.row] {
        cell.accessoryType = .None
    } else if checked[indexPath.row] {
        cell.accessoryType = .Checkmark
    }
    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if let cell = tableView.cellForRowAtIndexPath(indexPath) {
        if cell.accessoryType == .Checkmark {
             cell.accessoryType = .None
             checked[indexPath.row] = false
        } else {
             cell.accessoryType = .Checkmark
             checked[indexPath.row] = true
        }
    }    
}

To reset all the checkboxes:

func resetChecks() {
   for i in 0.. < tableView.numberOfSections {
       for j in 0.. < tableView.numberOfRowsInSection(i) {
            if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: j, inSection: i)) {
               cell.accessoryType = .None
            }
       }
   }
}
查看更多
小情绪 Triste *
4楼-- · 2020-01-27 12:12

Since I didn't see anyone list this, you can create a custom UITableViewCell that will toggle the checkmark with selection by overriding it's setSelected() method and defaulting .selectionStyle to .gray:

class CheckableTableViewCell: UITableViewCell {

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        selectionStyle = .gray
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        accessoryType = selected ? .checkmark : .none
    }
}
查看更多
Melony?
5楼-- · 2020-01-27 12:13

A UITableView keeps selected state for single or multiple selections. So IMO there would need to be a very good reason for keeping an entire parallel state somewhere. If you want to just change the cell's appearance based on select state, do it in the cell.

In your UITableViewCell subclass, override setSelected like so:

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
    self.accessoryType = selected ? .checkmark : .none
}

No need to use any table view delegate methods.

Note: You have to call super.setSelected otherwise the cell doesn't keep the selected state correctly.

查看更多
我命由我不由天
6楼-- · 2020-01-27 12:14

Updated In swift 4.2 Every New selection Remove previous Check mark

   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print(self.coloursArray[indexPath.row])

     self.tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    self.tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
查看更多
对你真心纯属浪费
7楼-- · 2020-01-27 12:21

Swift 5.0

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)

    if let cell = tableView.cellForRow(at: indexPath) {
        resetChecks()
        cell.accessoryType = .checkmark
    }
}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    self.tableView.cellForRow(at: indexPath)?.accessoryType = .none
}

func resetChecks() {
    for i in 0..<tableView.numberOfSections {
        for j in 0..<tableView.numberOfRows(inSection: i) {
            if let cell = tableView.cellForRow(at: IndexPath(row: j, section: i)) {
                cell.accessoryType = .none
            }
        }
    }
}
查看更多
登录 后发表回答