2012-04-17 22 views
15

你会认为这很容易。使用这段代码,我可以检查表中的多行,但我想要的是一次只检查一行。如果用户选择不同的行,那么我希望旧行只是自动取消选中。不知道该怎么做。这是我的代码:UITableView选中对号一次只有一行

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

[tableView deselectRowAtIndexPath:indexPath animated:YES]; 


UITableViewCell *theCell = [tableView cellForRowAtIndexPath:indexPath]; 

if (theCell.accessoryType == UITableViewCellAccessoryNone) { 
    theCell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } 

    else if (theCell.accessoryType == UITableViewCellAccessoryCheckmark) { 
    theCell.accessoryType = UITableViewCellAccessoryNone; 
    } 
} 

感谢您的任何帮助,你可以借!

+1

对于那些被正确回答的问题,您应该点击旁边的复选标记以接受正确答案。 – 2012-04-17 14:51:36

回答

22

最好的办法是设置的cellForRowAtIndexPath附件类型和使用didSelectRowAtIndexPath方法只哪个路径应该选择记录,然后调用reloadData。

+1

此解决方案的唯一问题是您将失去取消选择行动画。只需重新加载其他可见单元格。 – 2012-04-17 16:03:48

+1

我绝对选择正确的第一个和稍后......如果有必要。 :-) – 2012-04-17 16:08:16

+1

再次感谢您! reloadData是使事情发挥作用的关键。非常感谢您的洞察力。 – Jupiter869 2012-04-17 21:09:02

17

您可以创建一个新变量来跟踪在didSelectRowAtIndex处选择的索引。

int selectedIndex; 

在你的cellForRowAtIndexPath

if(indexPath.row == selectedIndex) 
{ 
    cell.accessoryType = UITableViewCellAccessoryCheckmark; 
} 
else 
{ 
    cell.accessoryType = UITableViewCellAccessoryNone; 
} 

,并在您didSelectRowAtIndex

selectedIndex = indexPath.row; 
[tableView reloadData]; 
+0

请声明为NSINTEGER而不是int – Arun 2016-07-19 09:25:24

4

简单的方法就是保存所选IndexPath,并检查它的cellForRowAtIndexPath。

附着是代码:

步骤1:初始化selectedIndexPath selectedIndexPath = [[NSIndexPath的alloc] INIT];

第2步:在的cellForRowAtIndexPath

if([selectedIndexPath isEqual:indexPath]){ 
    [checkMark setHidden:NO]; 
} else { 
    [checkMark setHidden:YES]; 
} 

第3步:在didSelectRowAtIndexPath方法

selectedIndexPath = indexPath; 
[tableView reloadData]; 

它应该工作试试这个恩乔伊:)

8

你并不需要重新加载的tableView 。

请参见下面的代码:

声明一个NSIndexPath lastSelectedIndexPath变量类

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    if(lastSelectedIndexPath) { 

     UITableViewCell *lastCell = [tableView cellForRowAtIndexPath:lastSelectedIndexPath]; 
     [lastCell setAccessoryView:nil]; 
    } 

    UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:currentIndexPath]; 
    [currentCell setAccessoryView:UITableViewCellAccessoryCheckmark]; 

    lastSelectedIndexPath = indexPath; 
} 
+0

有谁知道如何使用NSUserDeafults保存所选行的状态?我一直在寻找一种简单的方法来做到这一点。我发现的所有解决方案都相当复杂,而且对于我的项目来说,这会让我的代码更加混乱。 – 2014-03-08 06:31:34

+0

@Borges你能解释一下你的问题吗?一个细胞的状态究竟意味着什么? – 2014-03-09 07:28:01

71
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; 
} 

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; 
} 

Swift版本将是:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark 
} 

func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { 
    tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None 
} 

Swift 3更新

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

最好的解决方案!谢谢! – 2014-09-10 17:23:21

+0

@ThomásC。同意! – mikemike396 2014-09-30 15:04:01

+2

这不关心可重用性。小心。 – p0lAris 2015-05-18 22:24:39

0
Swift iOS 

    var checkedIndexPath : NSIndexPath? 

    // table row which row was selected 
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath!) { 
     tableView.deselectRowAtIndexPath(indexPath, animated: true) 

     println("Section #\(indexPath.section)! You selected cell #\(indexPath.row)!") 

     if (self.checkedIndexPath != nil) { 
      var cell = tableView.cellForRowAtIndexPath(self.checkedIndexPath!) 
      cell?.accessoryType = .None 
     } 

     var cell = tableView.cellForRowAtIndexPath(indexPath) 
     cell?.accessoryType = .Checkmark 

     self.checkedIndexPath = indexPath 

    }// end tableView 
+0

它崩溃时, 'checkedIndexPath' 是不是在TableView中VisibleCells 如果(self.checkedIndexPath!=无){VAR 细胞= tableView.cellForRowAtIndexPath(self.checkedIndexPath!) 细胞?.accessoryType = .None } 如果不在可见单元格中,单元格为零 – umakanta 2015-09-15 12:34:54

1

试试这个:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    if indexPath.section == 1 { 
     // un-select the older row 
     if let selected = self.LastSelected { 
      tableView.cellForRowAtIndexPath(selected)?.accessoryType = .None 
     } 

     // select the new row 
     tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = UITableViewCellAccessoryType.Checkmark 
     self.LastSelected = indexPath 
    } 
} 
10

您不需要(也不应该)刚刚刷新每次选择后的表。

关于如何管理选择列表,Apple有很好的documentation。有关示例,请参见清单6-3。

这或多或少与其他一些答案相同,但我想我会添加更多的细节。

你想要做的是将当前选定的IndexPath保存到一个变量,并使用didSelectRowAtIndexPath中的删除旧的复选标记。这也是您将添加新复选标记的地方。

您还需要确保还设置/取消设置cellForRowAtIndexPath中的复选标记,否则如果列表很大并且单元格被重用,它将看起来像选择了多行。这是一些其他答案的问题。

见SWIFT 2.0下面的例子:

// for saving currently seletcted index path 
var selectedIndexPath: NSIndexPath? = NSIndexPath(forRow: 0, inSection: 0) // you wouldn't normally initialize it here, this is just so this code snip works 
// likely you would set this during cellForRowAtIndexPath when you dequeue the cell that matches a saved user selection or the default 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    // this gets rid of the grey row selection. You can add the delegate didDeselectRowAtIndexPath if you want something to happen on deselection 
    tableView.deselectRowAtIndexPath(indexPath, animated: true) // animated to true makes the grey fade out, set to false for it to immediately go away 

    // if they are selecting the same row again, there is nothing to do, just keep it checked 
    if indexPath == selectedIndexPath { 
     return 
    } 

    // toggle old one off and the new one on 
    let newCell = tableView.cellForRowAtIndexPath(indexPath) 
    if newCell?.accessoryType == UITableViewCellAccessoryType.None { 
     newCell?.accessoryType = UITableViewCellAccessoryType.Checkmark 
    } 
    let oldCell = tableView.cellForRowAtIndexPath(selectedIndexPath!) 
    if oldCell?.accessoryType == UITableViewCellAccessoryType.Checkmark { 
     oldCell?.accessoryType = UITableViewCellAccessoryType.None 
    } 

    selectedIndexPath = indexPath // save the selected index path 

    // do whatever else you need to do upon a new selection 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) 
    // if this is the currently selected indexPath, set the checkmark, otherwise remove it 
    if indexPath == selectedIndexPath { 
     cell.accessoryType = UITableViewCellAccessoryType.Checkmark 
    } else { 
     cell.accessoryType = UITableViewCellAccessoryType.None 
    } 
} 
+0

这是一个很好的答案。 – damianesteban 2016-04-27 16:33:13

+0

这个答案很奇妙,但是它假设'selectedIndexPath'被初始化了,不是吗?我的意思是,如果在初始化表视图时没有默认值,'didSelectRowAtIndexPath'应该尝试展开'selectedIndexPath'并设置值 – matteodv 2017-08-31 14:54:32

+0

@matteodv,在我的代码片段中我对第三行有一个评论,当您将与保存的用户选择或缺省值相匹配的单元出列时,可能会在cellForRowAtIndexPath期间设置此值。这是否回答你的问题? – jeffjv 2017-09-01 20:13:46

0

在雨燕2.0我用这个:

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

    if((lastSelectedIndexPath) != nil) { 
     let lastCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath) 
     lastCell?.accessoryType = UITableViewCellAccessoryType.None 
    } 

    let currentCell = tableView.cellForRowAtIndexPath(indexPath) 
    currentCell?.accessoryType = UITableViewCellAccessoryType.Checkmark 

    lastSelectedIndexPath = indexPath 

} 
+0

lastSelectedIndexPath如何初始化和管理? as lastSelectedIndexPath永远不可以为零 – 2016-03-02 07:37:04

+0

var lastSelectedIndexPath:NSIndexPath? = NSIndexPath(forRow:0,inSection:0) – 2016-03-02 08:34:41

+0

'var lastSelectedIndexPath:NSIndexPath!'在开始时为零,但之后,我检查if是否为nil,并且在函数结尾处我做了:'lastSelectedIndexPath = indexPath' – Dasoga 2016-03-02 14:42:26

1

在斯威夫特,以下作品完美:

lastSelectedIndexPath = NSIndexPath(forRow: 1, inSection: 0)//Row will be the previous selected row 


    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
{ 
    let cell:LabelsSelectionCell = tableView.dequeueReusableCellWithIdentifier("LabelsSelectionCell", forIndexPath: indexPath) as! LabelsSelectionCell 
    cell.setCellLael(labelOptionsArray[indexPath.row]) 
    if lastSelectedIndexPath == indexPath 
    { 
     cell.setCellCheckedStatus(true) 
    } 
    return cell 
} 
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
{ 
    if let _ = lastSelectedIndexPath 
    { 
     let lastCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath!) as! LabelsSelectionCell 
     lastCell.setCellCheckedStatus(false) 
    } 
    let currentCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(indexPath) as! LabelsSelectionCell 
    currentCell.setCellCheckedStatus(true) 

    lastSelectedIndexPath = indexPath 

    tableView.deselectRowAtIndexPath(indexPath, animated: true) 
} 
0

我的办法是取消其他细胞选择期间:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = .... 

    if condition { 
     cell.accessoryType = .checkmark 
     tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.bottom) 
    } else { 
     cell.accessoryType = .none 
    } 

    return cell 
} 

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    for row in 0...tableView.numberOfRows(inSection: 0) { 
     if row == indexPath.row {continue} 
     tableView.deselectRow(at: IndexPath(row: row, section: 0), animated: true) 
    } 

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

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

对于斯威夫特3以下为我工作:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    tableVIew.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark 
} 

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

不工作的人。:( – Ashik 2017-09-15 17:36:46

+0

尝试使用ckeckmark单元格样式 – Tarik 2017-09-25 12:24:52

0

这里就是我来了,当我有这个问题。
此代码在最新版本的Swift中实施,截至今天...
欲了解更多信息和/或扩展文件,请查看该片段的Github Gist

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {  
    if let sip = selectedIndex { 
     tableView.deselectRow(at: sip, animated: false) 
    } 
    selectedIndex = indexPath 
} 

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 
    if selectedIndex?.row == indexPath.row { 
     selectedIndex = nil 
    } 
} 
0

测试,并解决了尝试这个它完美地工作

添加为全局变量

var selectedIndexPath = NSIndexPath(row: 0, section: 0) 

在didselect方法添加此

 // old one check off 
     if indexPath != selectedIndexPath as IndexPath { 
      let oldCell = categorytable.cellForRow(at: selectedIndexPath as IndexPath) 
      if oldCell?.accessoryView != nil { 
       oldCell?.accessoryView = nil 
      } 
      else { 
       let imageName = "checkmark" 
       let image: UIImageView = UIImageView(image: UIImage(named: imageName)) 
       cell.accessoryView = image 
      } 
     } 
     // the new one on 

     if cell.accessoryView == nil { 
      let imageName = "checkmark" 
      let image: UIImageView = UIImageView(image: UIImage(named: imageName)) 
      cell.accessoryView = image 
     } 
     else { 
      cell.accessoryView = nil 
     }