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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:54:28  来源:igfitidea点击:

UITableView Checkmark ONLY ONE Row at a Time

iosxcodeios4ios5xcode4

提问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;
}

Swiftversion 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 3update:

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