【问题标题】:UITableViewCell checkmark to be toggled on and off when tapped点击时打开和关闭 UITableViewCell 复选标记
【发布时间】:2015-07-15 14:01:38
【问题描述】:

我正在开发一个表格视图

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

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

// 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 个部分)

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

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

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) {




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

}

【问题讨论】:

    标签: ios uitableview swift checkmark


    【解决方案1】:

    试试这个:

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

    【讨论】:

    • 非常感谢它没有带来错误但没有显示复选标记,
    • 我发现我复制它时出错了,当我把它放进去时,它显示 cell.accessoryType = row == 的错误告诉我 row 是一个未解析的标识符......我知道与 row 一起工作,因为我上面的代码有它,
    • 好的,你的问题是什么?
    • 更好地更新模型,例如 let isChecked = checked[indexPath.row]; checked[indexPath.row] = !isChecked 在 didSelectRowAtIndexPath 中并调用 reloadRowsAtIndexPaths。
    • Set&lt;NSIndexPath&gt; 是比Bool 数组更好的数据结构
    【解决方案2】:

    斯威夫特 > 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
    }
    

    【讨论】:

    • 你在检查初始条件时忘记了 if 语句中的 {
    • 有些条件是什么?
    • 这正是我现在正在使用的,这是正确的答案。话虽如此,这在使用 swift 3 语法的 Swift 3 中不再起作用。我现在正在寻找解决方案
    • 在 Swift 3 中使用一个函数解决:stackoverflow.com/a/44255293/3849039
    【解决方案3】:

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

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

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

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

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

    【讨论】:

    • 这是最优雅的解决方案,它也适用于可重用的 tableviewCells!谢谢!
    • 有史以来最好的解决方案。单选按钮
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

      • 这将导致复选标记出现在不应出现的单元格上,因为单元格被重复使用。
      【解决方案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
              }
          }
      }
      

      }

      【讨论】:

      • 这个答案确保当滚动表格视图时,只有用户选择的单元格/索引才会有复选标记。否则,当滚动发生时,复选标记将出现在多个(未选中)位置。关键在于评论//configure your cell here 不幸的是,我错过了这个金块,不得不自己敲敲敲打才能弄清楚。
      【解决方案7】:
      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
          }
      }
      

      【讨论】:

        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

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

          【讨论】:

            【解决方案10】:

            由于我没有看到任何人列出此内容,因此您可以创建一个自定义 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
                }
            }
            

            【讨论】:

              【解决方案11】:

              对于 Swift 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
                  }
              }
              

              【讨论】:

                【解决方案12】:

                其他人指出的简单解决方案是.checkmarkdidSelectRowAt 方法中的行,并在didDeselectRowAt方法中将行设置为.none,如下所示...

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

                【讨论】:

                  【解决方案13】:

                  为我完成的最简单的解决方案(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
                  }
                  

                  【讨论】:

                    【解决方案14】:

                    我已经使用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
                             }
                         }
                         
                         
                     }
                    

                    【讨论】:

                      【解决方案15】:

                      适用于使用单次使用复选标记的任何人。

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

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2018-06-11
                        • 1970-01-01
                        • 2022-12-08
                        • 1970-01-01
                        相关资源
                        最近更新 更多