47

我正在处理一个表格视图

我希望能够点击每个单元格,当点击时,它会在单元格上显示一个复选标记

现在我有一些代码可以使这项工作:

// 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
        }
    }
}

但此代码仅在一个部分中选择 1 个单元格(我有 5 个部分)

我需要它来选择任何地方的任何单元格

此外,当我上下拖动屏幕时,我会通过复选标记丢失

视图控制器.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) {




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

}
4

15 回答 15

81

斯威夫特 > 3.0

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    if let cell = tableView.cellForRow(at: indexPath) {
        cell.accessoryType = .none
    }
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if let cell = tableView.cellForRow(at: indexPath) {
        cell.accessoryType = .checkmark

    }
}

我通过使用两个 Swift 函数来解决:didSelectRowAtIndexPath 和 didDeselectRowAtIndexPath。

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    if let cell = tableView.cellForRowAtIndexPath(indexPath) {
        cell.accessoryType = .None
    }
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if let cell = tableView.cellForRowAtIndexPath(indexPath) {
        cell.accessoryType = .Checkmark

    }
}

为了使它正常工作,在您的 cellForRowAtIndexPath 函数中添加一行代码,以便在屏幕上绘制表格视图时选择一行,否则在您第一次选择另一行时将不会调用 didDeselectRowAtIndexPath。像这样:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cellData", forIndexPath: indexPath) 
    if (some condition to initially checkmark a row)
        cell.accessoryType = .Checkmark
        tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.Bottom)
    } else {
        cell.accessoryType = .None
    }

    return cell
}
于 2016-01-23T11:37:49.627 回答
37

尝试这个:

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
        }
    }    
}

要重置所有复选框:

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
            }
       }
   }
}
于 2015-05-05T17:43:33.717 回答
24

UITableView 为单个或多个选择保持选中状态。因此,IMO 需要有一个很好的理由将整个并行状态保持在某个地方。如果您只想根据选择状态更改单元格的外观,请在单元格中进行。

在您的 UITableViewCell 子类中,像这样覆盖 setSelected:

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

无需使用任何表视图委托方法。

注意:您必须调用 super.setSelected 否则单元格无法正确保持选定状态。

于 2016-08-23T22:47:16.513 回答
19

Swift 3.0
只使用一个函数来保持简单

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
        } else {
            cell.accessoryType = .checkmark
        }
    }   
}
于 2017-05-30T06:45:27.107 回答
13

斯威夫特 3.0

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if let cell = tableView.cellForRow(at: indexPath) {
        cell.accessoryType = .checkmark
    }
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    if let cell = tableView.cellForRow(at: indexPath) {
        cell.accessoryType = .none
    }
}
于 2016-12-14T02:47:04.443 回答
6

Swift 4.0,现在一起:

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
        }
    }
}

}

于 2018-05-01T18:05:18.127 回答
2

正如其他人所指出的那样,简单的解决方案是方法中.checkmark的行didSelectRowAt并将行设置为.none方法 didDeselectRowAt中的如下...

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

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

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

但是,如果您在加载表格时选择了默认行,您首先需要在选择其他行时取消选择它,在这种情况下,请在didSelectRowAt方法中使用下面的代码。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    for row in 0..<tableView.numberOfRows(inSection: indexPath.section) {
        if let cell = tableView.cellForRow(at: IndexPath(row: row, section: indexPath.section)) {
            cell.accessoryType = row == indexPath.row ? .checkmark : .none
        }
    }
}
于 2020-08-12T14:07:04.493 回答
1

为我做的最简单的解决方案(Swift 5.2)

override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    // Remove checkmark from the row that is currently showing it before adding to one being selected
    if let currentIndexPath = tableView.indexPathForSelectedRow {
        self.tableView.cellForRow(at: currentIndexPath)?.accessoryType = .none
    }

    return indexPath
}

override public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
于 2020-09-02T02:59:22.587 回答
1

斯威夫特 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
            }
        }
    }
}
于 2019-04-30T18:46:11.917 回答
1

对于斯威夫特 5:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
        cell.accessoryType = .checkmark
    }

}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
        cell.accessoryType = .none
    }
}
于 2019-10-31T21:41:07.660 回答
1

对于使用一次复选标记的任何人。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
       
        tableView.deselectRow(at: indexPath, animated: true)
        
        //  checkmark logic
        if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
                if cell.accessoryType != .checkmark {
                    resetChecks()
                    cell.accessoryType = .checkmark
                }
            }
    }
func resetChecks() {
        for i in 0..<tableView.numberOfSections {
            for j in 0..<tableView.numberOfRows(inSection: i) {
                if let cell = tableView.cellForRow(at: NSIndexPath(row: j, section: i) as IndexPath) {
                    cell.accessoryType = .none
                }
           }
       }
    }
于 2021-02-23T20:32:50.437 回答
0
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    if self.checkedIndex == indexPath.row{

    }else{
        let cell = tableView.cellForRow(at: indexPath)
        cell?.accessoryType = .checkmark
        let indexPathh = IndexPath(row: checkedIndex, section: 0)
        let UnCheckCell = tableView.cellForRow(at: indexPathh)
        UnCheckCell?.accessoryType = .none
        checkedIndex = indexPath.row
    }
}
于 2019-02-13T10:23:52.343 回答
0

由于我没有看到任何人列出这个,您可以创建一个自定义UITableViewCell,通过覆盖它的setSelected()方法并默认.selectionStyle.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
    }
}
于 2019-08-17T15:24:28.490 回答
0

我已经使用tableView(_:didSelectRowAt:), 委托方法来完成在单元格上放置复选标记并在再次点击单元格时将其删除的功能。这是代码:

//MARK:-create delegate methode that is fired when a cell is clicked
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     tableView.deselectRow(at: indexPath , animated: true)


     if  let cell = tableView.cellForRow(at: indexPath){
         if cell.accessoryType == .checkmark {
             cell.accessoryType = .none
         }
         else {
             cell.accessoryType = .checkmark
         }
     }
     
     
 }
于 2020-09-02T18:49:47.377 回答
0

在 swift 4.2 中更新了每个新选择删除以前的复选标记

   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
}
于 2019-04-21T05:29:16.083 回答