ios 如何以编程方式选择 uitableview 行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14411249/
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 21:55:15  来源:igfitidea点击:

How do you select uitableview rows programmatically

iosobjective-ccocoa-touchuitableview

提问by S.J

I am trying to achive a email like select all functionality in uitableview where on same button tap user can checkmark or remove all checkmark and additionally user can also select/deselect rows(on didSelectRowAtIndexPath). I tried to do but its not working properly, here is my code.

我正在尝试在 uitableview 中选择像选择所有功能这样的电子邮件,其中在同一个按钮上,用户可以选中或删除所有选中标记,另外用户还可以选择/取消选择行(在 didSelectRowAtIndexPath 上)。我试图这样做,但它不能正常工作,这是我的代码。

- (IBAction)selectAll:(id)sender
{
    if(myBoolean)
    {
        for (NSInteger s = 0; s < self.iTable.numberOfSections; s++)
        {
            for (NSInteger r = 0; r < [self.iTable numberOfRowsInSection:s]; r++)
            {
                [[self.iTable cellForRowAtIndexPath:[NSIndexPath indexPathForRow:r inSection:s]] setAccessoryType:UITableViewCellAccessoryNone];
            }
        }

        myBoolean = NO;

        [_selectUnselectButton setTitle:@"Select all Friends" forState:UIControlStateNormal];
    }
    else
    {
        for (NSInteger s = 0; s < self.iTable.numberOfSections; s++)
        {
            for (NSInteger r = 0; r < [self.iTable numberOfRowsInSection:s]; r++)
            {
                [[self.iTable cellForRowAtIndexPath:[NSIndexPath indexPathForRow:r inSection:s]] setAccessoryType:UITableViewCellAccessoryCheckmark];
                NSLog(@"%d-%d",s,r);
            }
        }

        myBoolean = YES;

        [_selectUnselectButton setTitle:@"Unselect all Friends" forState:UIControlStateNormal];
    }
}


-(void)tableView:(UITableView *)tableView_ didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView_ cellForRowAtIndexPath:indexPath];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

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

回答by vikingosegundo

I wrote a sample codethat I adapted to your needs.

我编写了一个示例代码,可以满足您的需求。

Basically it is

基本上是

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *unifiedID = @"aCellID";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:unifiedID];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:unifiedID];
    }

    cell.textLabel.text = [self.states objectAtIndex:indexPath.row];

    //if the indexPath was found among the selected ones, set the checkmark on the cell
    cell.accessoryType = ([self isRowSelectedOnTableView:tableView atIndexPath:indexPath]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
    return cell;

}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *state = [self.states objectAtIndex:indexPath.row];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if([self isRowSelectedOnTableView:tableView atIndexPath:indexPath]){
        [self.selectedCells removeObject:indexPath];
        [self.selecedStates removeObject:state];
        cell.accessoryType = UITableViewCellAccessoryNone;
    } else {
        [self.selectedCells addObject:indexPath];
        [self.selecedStates addObject:state];
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

    NSLog(@"%@", self.selecedStates);
}


-(BOOL)isRowSelectedOnTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath
{
    return ([self.selectedCells containsObject:indexPath]) ? YES : NO;
}


- (IBAction)selectAll:(id)sender {

    [self.selecedStates removeAllObjects];
    [self.selectedCells removeAllObjects];
    NSUInteger numberOfSections = [self.tableView numberOfSections];
    for (NSUInteger s = 0; s < numberOfSections; ++s) {
        NSUInteger numberOfRowsInSection = [self.tableView numberOfRowsInSection:s];
        for (NSUInteger r = 0; r < numberOfRowsInSection; ++r) {
            NSIndexPath *idxPath = [NSIndexPath indexPathForRow:r inSection:s];
            [self.selectedCells addObject:idxPath];
            [self.selecedStates addObject:self.states[idxPath.row]];
        }
    }
    [self.tableView reloadData];
}



- (IBAction)deselectAll:(id)sender {
    [self.selecedStates removeAllObjects];
    [self.selectedCells removeAllObjects];
    [self.tableView reloadData];
}


- (IBAction)toggleAll:(id)sender {
    if ([self.states count] == [self.selecedStates count]) {
        [sender setTitle:@"select all"];
        [self deselectAll:sender];
    } else {
        [sender setTitle:@"deselect all"];
        [self selectAll:sender];
   }
}

in action:

在行动:

enter image description here

在此处输入图片说明

You are calling

你在打电话

[[self.iTable cellForRowAtIndexPath:[NSIndexPath indexPathForRow:r inSection:s]] setAccessoryType:UITableViewCellAccessoryNone];

for every row in every section within the tableView. if you have many row, this is ver inefficient, as it will deal with rows not on the screen. But this is not needed. just put every selected index path into an array and tell the tableView to reload. This will reload the visible cells and due to the implementation of -tableView:cellForRowAtIndexPath:cells wfor new rows will be correctly re-conigured.

对于 tableView 中每个部分中的每一行。如果你有很多行,这是非常低效的,因为它会处理不在屏幕上的行。但这不是必需的。只需将每个选定的索引路径放入一个数组中,然后告诉 tableView 重新加载。这将重新加载可见单元格,并且由于-tableView:cellForRowAtIndexPath:单元格 wfor 新行的实现将被正确地重新配置。

回答by dasblinkenlight

Setting the accessory view needs to happen insidethe tableView:cellForRowAtIndexPath:method. When you want to change the accessories from outside, the outside method needs to change the model first to indicate that check marks must be placed in certain cells, and then call reloadDataon the UITableView.

设置附件视图需要在方法内部进行tableView:cellForRowAtIndexPath:。如果你想改变来自外部的配件,外面的方法需要改变模型首先表明,复选标记必须放置在特定的细胞中,然后调用reloadDataUITableView

One way to store what cells are checked is an array of NSIndexSetobjects - one index set per section. In the example below I show code for a single section, but you should get an idea of how to make multiple sections work.

存储检查的单元格的一种方法是NSIndexSet对象数组- 每个部分设置一个索引。在下面的示例中,我展示了单个部分的代码,但您应该了解如何使多个部分工作。

// This variable needs to be declared in a place where your data source can get it
NSMutableIndexSet *selected;

// You need to initialize it in the designated initializer, like this:
selected = [[NSMutableIndexSet alloc] init];

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    if ([selected containsIndex:indexPath.row]) {
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
    } else {
        [cell setAccessoryType:UITableViewCellAccessoryNone];
    }
    // Do the rest of your code
    return cell;
}

Now in the code where you want to set rows selected or unselected you just need to call [selected addIndex:rowToSelect]or [selected removeIndex:rowToUnselect], and call your table's reloadData.

现在,在要设置选中或未选中行的代码中,您只需要调用[selected addIndex:rowToSelect][selected removeIndex:rowToUnselect],然后调用表的reloadData.

回答by Inder Kumar Rathore

回答by Dixit Patel

Try this code instead of your old one

试试这个代码而不是你的旧代码

- (IBAction)selectAll:(id)sender
{
    if(myBoolean)
    {
        for (NSInteger s = 0; s < self.iTable.numberOfSections; s++)
        {
            for (NSInteger r = 0; r < [self.iTable numberOfRowsInSection:s]; r++)
            {
              [self.iTable selectRowAtIndexPath:[NSIndexPath indexPathForRow:r inSection:s]] animated:YES scrollPosition:UITableViewScrollPositionNone];

            }
        }

        myBoolean = NO;

        [_selectUnselectButton setTitle:@"Select all Friends" forState:UIControlStateNormal];
    }
    else
    {
        for (NSInteger s = 0; s < self.iTable.numberOfSections; s++)
        {
            for (NSInteger r = 0; r < [self.iTable numberOfRowsInSection:s]; r++)
            {
                 [self.iTable selectRowAtIndexPath:[NSIndexPath indexPathForRow:r inSection:s]] animated:YES scrollPosition:UITableViewScrollPositionNone];
                NSLog(@"%d-%d",s,r);
            }
        }

        myBoolean = YES;

        [_selectUnselectButton setTitle:@"Unselect all Friends" forState:UIControlStateNormal];
    }
}


-(void)tableView:(UITableView *)tableView_ didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView_ cellForRowAtIndexPath:indexPath];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

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

回答by Hemang

You can follow these steps to implement this,

您可以按照以下步骤来实现这一点,

1) You should have a mutablearray to store indexpaths

1)你应该有一个mutable数组来存储索引路径

2) What you can do is, when you tap Check All or Uncheck All, do addor removeall indexpaths to/from array (which you've), reload table for update changes

2)您可以做的是,当您点击“全部检查”或“取消全部检查”时,执行addremove所有索引路径到/来自数组(您已经),重新加载表以进行更新更改

3) In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPathdatasource method, check into array using if([array containsObject:indexPath]), if exist mark it checkedor unchecked

3) 在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath数据源方法中,使用 检入数组if([array containsObject:indexPath]),如果存在则标记它checkedunchecked

4) In - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPathdelegate method, you should check for already existence of indexpath tapped into array, as you've did in 3rd step, and addor removeindexpathsas per the condition, reload table for update changes

4)在- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath委托方法中,您应该检查索引路径是否已经存在于数组中,就像您在第三步中所做的那样,并根据条件添加删除indexpaths,重新加载表以进行更新更改

回答by Siba Prasad Hota

Take another NSMutableArrayas SelectedArray

取另一个NSMutableArray作为SelectedArray

in didSelectRowAtIndexPathrow You can Add remove objects from SelectedArray.

didSelectRowAtIndexPath排可以从添加删除对象SelectedArray

You can select a UITableViewCellcalling UITableViewsselectRowAtIndexPathmethod:

您可以选择UITableViewCell调用UITableViewsselectRowAtIndexPath方法:

[yourtable selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 
                       animated:NO 
                 scrollPosition:UITableViewScrollPositionTop];

Put for loop for selectedArrayto putcheckmark only in selected cells or All cells.

selectedArray放置循环以仅在选定单元格或所有单元格中放置复标记。

check my accepted answer here : Need to create a select all button for UITableView and add selections to an array in iOS

在这里检查我接受的答案:需要为 UITableView 创建一个全选按钮并将选择添加到 iOS 中的数组

回答by Abdul Karim

  • Xcode 8x
  • Xcode 8x
  • Swift 3x

    Select Row

    let indexPath = IndexPath(row: 0, section: 0)
    mytableView.selectRow(at: indexPath, animated: true, scrollPosition: .bottom)
    myTableView.delegate?.tableView!(myTableView, didSelectRowAt: indexPath)
    

    DeSelect Row

    let deselectIndexPath = IndexPath(row: 7, section: 0)
    myTableView.deselectRow(at: deselectIndexPath, animated: true)
    myTableView.delegate?.tableView!(tblView, didDeselectRowAt: indexPath)
    
  • 斯威夫特 3 倍

    选择行

    let indexPath = IndexPath(row: 0, section: 0)
    mytableView.selectRow(at: indexPath, animated: true, scrollPosition: .bottom)
    myTableView.delegate?.tableView!(myTableView, didSelectRowAt: indexPath)
    

    取消选择行

    let deselectIndexPath = IndexPath(row: 7, section: 0)
    myTableView.deselectRow(at: deselectIndexPath, animated: true)
    myTableView.delegate?.tableView!(tblView, didDeselectRowAt: indexPath)
    
  • 回答by lakesh

    you can do something like this:

    你可以做这样的事情:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        [self doSomethingWithRowAtIndexPath:indexPath];
    }