ios UITableView 一次只勾选一行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10192908/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UITableView Checkmark ONLY ONE Row at a Time
提问by Jupiter869
You'd think this would be easy. With this code, I can check multiple rows in a table but what I WANT is to only have one row checked at a time. If a user selects a different row, then I want the old row to simply AUTOMATICALLY uncheck. Don't know how to do that. Here's my code:
你会认为这很容易。使用此代码,我可以检查表中的多行,但我想要的是一次只检查一行。如果用户选择了不同的行,那么我希望旧行简单地自动取消选中。不知道该怎么做。这是我的代码:
- (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;
}
}
Thanks for any help you can lend!
感谢您提供任何帮助!
回答by Ujwal Manjunath
- (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
version would be:
Swift
版本将是:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark
}
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None
}
Swift 3
update:
Swift 3
更新:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
Swift 5update
斯威夫特 5更新
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
}
回答by Phillip Mills
The best way is to set the accessory type in cellForRowAtIndexPath and use didSelectRowAtIndexPath to only record which path shouldbe selected and then call reloadData.
最好的方法是在cellForRowAtIndexPath中设置附件类型,使用didSelectRowAtIndexPath只记录应该选择哪个路径,然后调用reloadData。
回答by John Paul Manoza
You can create a new variable to track the index selected at didSelectRowAtIndex.
您可以创建一个新变量来跟踪在 didSelectRowAtIndex 中选择的索引。
int selectedIndex;
in your cellForRowAtIndexPath
在你的 cellForRowAtIndexPath
if(indexPath.row == selectedIndex)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
and in your didSelectRowAtIndex
并在你 didSelectRowAtIndex
selectedIndex = indexPath.row;
[tableView reloadData];
回答by jeffjv
You don't need to (and shouldn't) just reload the table after each selection.
您不需要(也不应该)刚刚刷新每次选择后的表。
Apple has good documentationon how to manage a selection list. See Listing 6-3 for an example.
Apple 有关于如何管理选择列表的良好文档。有关示例,请参见清单 6-3。
This is more or less the same answer as some of the others but I thought I'd add a little more detail.
这或多或少与其他一些答案相同,但我想我会添加更多细节。
What you want to do is save the current selected IndexPath to a variable and use that in didSelectRowAtIndexPath to remove the old check mark. This is also where you will be adding the new check mark.
您想要做的是将当前选定的 IndexPath 保存到一个变量中,并在 didSelectRowAtIndexPath 中使用它来删除旧的复选标记。这也是您将添加新复选标记的地方。
You need to make sure to also set/unset the checkmarks in cellForRowAtIndexPath otherwise if your list is large and cells are reused it will look like multiple rows are selected. This is a problem with some of the other answers.
您需要确保还设置/取消设置 cellForRowAtIndexPath 中的复选标记,否则如果您的列表很大并且单元格被重用,它看起来就像选择了多行。这是其他一些答案的问题。
See swift 2.0 example below:
请参阅下面的 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
}
}
回答by Burhanuddin Sunelwala
You don't need to reload the tableView.
您不需要重新加载 tableView。
See the below code:
请参阅以下代码:
Declare a NSIndexPath lastSelectedIndexPath
variable for your class
lastSelectedIndexPath
为你的类声明一个 NSIndexPath变量
- (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;
}
回答by Ranganatha G V
Simplest way is to save the selected IndexPath and check it in cellForRowAtIndexPath.
最简单的方法是保存选定的 IndexPath 并在 cellForRowAtIndexPath 中检查它。
attached is the code:
附上代码:
step 1: initialize selectedIndexPath selectedIndexPath = [[NSIndexPath alloc] init];
第一步:初始化 selectedIndexPath selectedIndexPath = [[NSIndexPath alloc] init];
step 2: in cellForRowAtIndexPath
第 2 步:在 cellForRowAtIndexPath 中
if([selectedIndexPath isEqual:indexPath]){
[checkMark setHidden:NO];
} else {
[checkMark setHidden:YES];
}
step 3 : In didSelectRowAtIndexPath
第 3 步:在 didSelectRowAtIndexPath 中
selectedIndexPath = indexPath;
[tableView reloadData];
It should work work try this Njoy :)
它应该可以工作,试试这个 Njoy :)
回答by mohsinj
I think https://stackoverflow.com/a/5960016/928599will help you.
I used it and it Works with deselectRowAtIndexPath too!
我认为https://stackoverflow.com/a/5960016/928599会帮助你。
我用过它,它也适用于 deselectRowAtIndexPath!
回答by Vinay Krishna Gupta
For Swift 3 following worked for me :
对于 Swift 3,以下对我有用:
override func viewDidLoad() {
super.viewDidLoad()
// allow cells to be selected
tableView.allowsSelection = true
// ensure that deselect is called on all other cells when a cell is selected
tableView.allowsMultipleSelection = false
}
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
}
回答by msmq
In Swift, following works perfectly:
在 Swift 中,以下工作完美:
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)
}
回答by alcedo
Try this:
尝试这个:
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
}
}