如何使用 UITableViewCellAccessoryCheckmark 取消选中所有行

发布于 2024-10-29 06:14:44 字数 989 浏览 6 评论 0原文

我有一个 UITableView,每行都包含一个使用 UITableViewCellAccessoryCheckmark 的复选框。我不知道如何使用 didSelectRowAtIndexPath 方法取消选中所有复选框。

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

    UITableViewCell *oldCell;

    int count = [self.myTableRowNamesArray count];

    for (NSUInteger i = 0; i < count; ++i) {                                
        // Uncheck all checkboxes
        // OF COURSE THIS DOESN'T WORK
        // BECAUSE i IS AN INTEGER AND INDEXPATH IS A POINTER
        FOO: oldCell = [myTableView cellForRowAtIndexPath:(int)i];
        // GOOD CODE:
        oldCell = [penanceOptionsTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        oldCell.accessoryType = UITableViewCellAccessoryNone;
    }
    UITableViewCell *newCell = [myTableView cellForRowAtIndexPath:indexPath];
    newCell.accessoryType = UITableViewCellAccessoryCheckmark;
}

I've got a UITableView with each row containing a checkbox using UITableViewCellAccessoryCheckmark. I can't figure out how to uncheck all the checkboxes using the didSelectRowAtIndexPath method.

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

    UITableViewCell *oldCell;

    int count = [self.myTableRowNamesArray count];

    for (NSUInteger i = 0; i < count; ++i) {                                
        // Uncheck all checkboxes
        // OF COURSE THIS DOESN'T WORK
        // BECAUSE i IS AN INTEGER AND INDEXPATH IS A POINTER
        FOO: oldCell = [myTableView cellForRowAtIndexPath:(int)i];
        // GOOD CODE:
        oldCell = [penanceOptionsTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        oldCell.accessoryType = UITableViewCellAccessoryNone;
    }
    UITableViewCell *newCell = [myTableView cellForRowAtIndexPath:indexPath];
    newCell.accessoryType = UITableViewCellAccessoryCheckmark;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

妄想挽回 2024-11-05 06:14:44

我建议不要修改 didSelectRowAtIndexPath: 中所有单元格的 .accessoryType,而是在某些 ivar 中存储所选索引,并更改 数据源的 -tableView:cellForRowAtIndexPath: 方法中的 .accessoryType ,即

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { 
   self.selectedIndexPath = indexPath;
   [tableView reloadData];
}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
   ...
   cell.accessoryType = [indexPath compare:self.selectedIndexPath] == NSOrderedSame
                          ? UITableViewCellAccessoryCheckmark
                          : UITableViewCellAccessoryNone;
   ...
}

只有可见单元格才会受到影响,屏幕外的数百万个其他单元格将不需要受到影响修改的。


完全正确,这是在选择单元格的一般情况下在 Swift 中的完整实现。您可以在类中的其他地方使用您认为合适的 selectedIndexPath 。例如,在cellForRowAtIndexPath中选择适当的单元格原型。

//  SelectingTableViewController

import UIKit

class SelectingTableViewController: UITableViewController   
    {
    internal var selectedIndexPath:NSIndexPath? = nil

    override func viewDidLoad()
        {
        super.viewDidLoad()
        tableView.estimatedRowHeight = 68.0
        tableView.rowHeight = UITableViewAutomaticDimension

        self.clearsSelectionOnViewWillAppear = false;
        }

    override func tableView
        (tableView:UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath)
            {
            print("did select....")

            // in fact, was this very row selected,
            // and the user is clicking to deselect it...
            // if you don't want "click a selected row to deselect"
            // then on't include this clause.
            if selectedIndexPath == indexPath
                {
                print("(user clicked on selected to deselect)")
                selectedIndexPath = nil
                tableView.reloadRowsAtIndexPaths(
                    [indexPath],
                    withRowAnimation:UITableViewRowAnimation.None)

                tableView.deselectRowAtIndexPath(indexPath, animated:false)
                return
                }

            // in fact, was some other row selected??
            // user is changing to this row? if so, also deselect that row
            if selectedIndexPath != nil
                {
                let pleaseRedrawMe = selectedIndexPath!
                // (note that it will be drawn un-selected
                // since we're chaging the 'selectedIndexPath' global)
                selectedIndexPath = indexPath
                tableView.reloadRowsAtIndexPaths(
                    [pleaseRedrawMe, indexPath],
                    withRowAnimation:UITableViewRowAnimation.None)
                return;
                }

            // no previous selection.
            // simply select that new one the user just touched.
            // note that you can not use Apple's willDeselectRowAtIndexPath
            // functions ... because they are freaky
            selectedIndexPath = indexPath
            tableView.reloadRowsAtIndexPaths(
                [indexPath],
                withRowAnimation:UITableViewRowAnimation.None)

            }

    }

Instead of modifying the .accessoryType of all cells in didSelectRowAtIndexPath:, I suggest storing the selected index in some ivar, and change the .accessoryType in the data source's -tableView:cellForRowAtIndexPath: method, i.e.

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { 
   self.selectedIndexPath = indexPath;
   [tableView reloadData];
}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
   ...
   cell.accessoryType = [indexPath compare:self.selectedIndexPath] == NSOrderedSame
                          ? UITableViewCellAccessoryCheckmark
                          : UITableViewCellAccessoryNone;
   ...
}

With this, only visible cells will be affected, and the million other cells outside of the screen won't need to be modified.


Quite right, here's a full implementation in Swift in the general case of selecting a cell .. you'd use selectedIndexPath elsewhere in the class as you see fit. For example, in cellForRowAtIndexPath to choose the appropriate cell prototype.

//  SelectingTableViewController

import UIKit

class SelectingTableViewController: UITableViewController   
    {
    internal var selectedIndexPath:NSIndexPath? = nil

    override func viewDidLoad()
        {
        super.viewDidLoad()
        tableView.estimatedRowHeight = 68.0
        tableView.rowHeight = UITableViewAutomaticDimension

        self.clearsSelectionOnViewWillAppear = false;
        }

    override func tableView
        (tableView:UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath)
            {
            print("did select....")

            // in fact, was this very row selected,
            // and the user is clicking to deselect it...
            // if you don't want "click a selected row to deselect"
            // then on't include this clause.
            if selectedIndexPath == indexPath
                {
                print("(user clicked on selected to deselect)")
                selectedIndexPath = nil
                tableView.reloadRowsAtIndexPaths(
                    [indexPath],
                    withRowAnimation:UITableViewRowAnimation.None)

                tableView.deselectRowAtIndexPath(indexPath, animated:false)
                return
                }

            // in fact, was some other row selected??
            // user is changing to this row? if so, also deselect that row
            if selectedIndexPath != nil
                {
                let pleaseRedrawMe = selectedIndexPath!
                // (note that it will be drawn un-selected
                // since we're chaging the 'selectedIndexPath' global)
                selectedIndexPath = indexPath
                tableView.reloadRowsAtIndexPaths(
                    [pleaseRedrawMe, indexPath],
                    withRowAnimation:UITableViewRowAnimation.None)
                return;
                }

            // no previous selection.
            // simply select that new one the user just touched.
            // note that you can not use Apple's willDeselectRowAtIndexPath
            // functions ... because they are freaky
            selectedIndexPath = indexPath
            tableView.reloadRowsAtIndexPaths(
                [indexPath],
                withRowAnimation:UITableViewRowAnimation.None)

            }

    }
荒岛晴空 2024-11-05 06:14:44
for (UITableViewCell *cell in [myTableView visibleCells]) {
    cell.accessoryType = UITableViewCellAccessoryNone;
}

但实际上,您最好只修改实际设置了复选标记的一个单元格。无论如何,您必须将此信息存储在模型中的某个位置。

for (UITableViewCell *cell in [myTableView visibleCells]) {
    cell.accessoryType = UITableViewCellAccessoryNone;
}

But really, you'd be better off just modifying the one cell that actually has the checkmark set. You have to have stored this information somewhere in your model anyway.

青萝楚歌 2024-11-05 06:14:44

您可能正在使用此方法设置某种属性。
所以我要做的是:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1. first unsetting the property
    [object someProperty:nil];

    // 2. call the reloadData method to uncheck all the checkmarks
    [tableView reloadData];

    // 3. check the selected cell
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [cell setAccessoryType:UITableViewCellAccessoryCheckmark];

    // 4. set the checked property
    [object setSomeProperty:[indexpath row]];
}

在我的 cellForRowAtIndexPath 方法中,我得到类似以下代码的内容:

    if([object someProperty] == [indexpath row]){
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];        
    } else {
        [cell setAccessoryType:UITableViewCellAccessoryNone];
    }

You're probably setting some kind of property with this method.
So what i do is:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1. first unsetting the property
    [object someProperty:nil];

    // 2. call the reloadData method to uncheck all the checkmarks
    [tableView reloadData];

    // 3. check the selected cell
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [cell setAccessoryType:UITableViewCellAccessoryCheckmark];

    // 4. set the checked property
    [object setSomeProperty:[indexpath row]];
}

And in my cellForRowAtIndexPath methods i got something like the following code:

    if([object someProperty] == [indexpath row]){
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];        
    } else {
        [cell setAccessoryType:UITableViewCellAccessoryNone];
    }
旧时模样 2024-11-05 06:14:44

是的,cellForRowAtIndexPath: 使用 NSIndexPath 而不是整数,因此

indexPathForRow:inSection:

如果您使用的是一个部分,则通过使用来创建索引路径,那么您的循环就可以了,只需在行中传递 i 并在部分中传递 0 即可。

Yes, cellForRowAtIndexPath: uses NSIndexPath instead of integer so make indexpath by using

indexPathForRow:inSection:

if you are using one section then your loop is fine just pass i in row and 0 for section.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文