UITableView中默认重新加载后如何记住选择的行并维护它们?

Posted

技术标签:

【中文标题】UITableView中默认重新加载后如何记住选择的行并维护它们?【英文标题】:How to remember rows selected and maintain them after reload by default in UITableView? 【发布时间】:2011-05-24 23:36:01 【问题描述】:

如何设置默认选中的行?我想选择一行,用indexpath.row 获取所选行的数量,然后重新加载表格并选择所选择的行。有人能帮助我吗?我可以在方法-(IBAction)segmentedControlIndexChanged 中获取选定的行吗?不在didSelectRowAtIndexPath

这是我的代码,如果它可以帮助你理解

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    
    //lbl1 = [[UILabel alloc]initWithFrame:CGRectMake(200, 10, 100, 20) ];

    // Configure the cell...
    NSString *depdateChoosed=[deparatureDates objectAtIndex:depSelectedIndice];
    NSString *comeateChoosed=[deparatureDates objectAtIndex:comSelectedIndice];
    NSString *choosedDate =[NSString stringWithFormat:@"%@%@",depdateChoosed, comeateChoosed];
    NSLog(@"date choisi %@ ",choosedDate);

    if(segment.selectedSegmentIndex==0)
    
        cell.textLabel.text =[deparatureDates objectAtIndex:indexPath.row];        
    
    else if(segment.selectedSegmentIndex==1) 
         //cell.textLabel.text =[goingBackDates objectAtIndex:indexPath.row];
        //cell.textLabel.text=[goingBackDates objectAtIndex:indexPath.row];
        cell.textLabel.text =[goingBackDates objectAtIndex:indexPath.row];
    
    return cell;



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

    NSLog(@" champ séléctionner : %d ",indexPath.row);

    if(segment.selectedSegmentIndex==0)
    
        depSelectedIndice=indexPath.row;  
    
    else if(segment.selectedSegmentIndex==1) 
        comSelectedIndice=indexPath.row;
    
    //[tableView reloadData];


-(IBAction) segmentedControlIndexChanged

    int i;
    switch (self.segment.selectedSegmentIndex) 
    
        case 0:
            i=0;

            [tableView reloadData];
            break;
        case 1:
            i=1;
            NSLog(@"dexieme segment selectionner");
            [tableView reloadData];
        default:
            break;
    

【问题讨论】:

【参考方案1】:
NSIndexPath *indexPath = [tableView indexPathForSelectedRow];

将为您提供当前选定行的NSIndexPath。然后你可以做

[tableView selectRowAtIndexPath:indexPath 
                       animated:NO 
                 scrollPosition:UITableViewScrollPositionMiddle];

稍后选择该行(并将其显示在屏幕中间)。

【讨论】:

方法 NSIndexPath indexPath = [tableView indexPathForSelectedRow];不能返回 int 吗? 另外,请确保您的UITableViewController 上的clearsSelectionOnViewWillAppear 设置为NO,否则会在视图出现时自动取消选择该行。这困扰了我好几个小时。 在我在viewDidAppear 中调用它之后,它适用于 ios 8【参考方案2】:

我也有同样的问题,我就是这样做的:

在你的tableViewController,在这个函数中添加这个

(UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    
    if(indexPath.row == 'the row you want to select')
    
        [tableView 
            selectRowAtIndexPath:indexPath 
            animated:TRUE 
            scrollPosition:UITableViewScrollPositionNone
        ];

        [[tableView delegate] 
            tableView:tableView 
            didSelectRowAtIndexPath:indexPath
        ];

    


【讨论】:

是的,以这种方式选择一个单元格,当它被处理到 tableView 时,确保即使你调用 [reloadData] 也会被选中。这似乎比在 [viewWillAppear] 中实现它更好。谢谢! 如果您的表格视图显示为动画,这是唯一的解决方案。不要在 viewDidLoad / viewDidAppear 中选择默认单元格! @refdev 如果表格很大,我不确定这种方法是否有效,因为不是所有的单元格都可以一次装箱(只有前 50 个左右),其他的单元格稍后需要.如果您的行低于初始限制,则if 中的代码永远不会执行,除非用户向下滚动。【参考方案3】:

这样就可以了:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition: UITableViewScrollPositionNone];

row 是您要选择的单元格编号(从 0 开始...),section 是单元格出现的部分。

【讨论】:

我有一个 UITableView 有 +130 行,这对我有用。我称之为viewWillAppear。 +1 谢谢【参考方案4】:

这是您在 UITableView 中预选一行的方式:

[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition: UITableViewScrollPositionNone];

将 indexPath 设置为您要选择的行,然后像上面一样进行方法调用。

【讨论】:

谢谢,但我不能使用 int 吗? tableView selectRowAtIndexPath:3 ? 您不能使用整数。您必须传入 indexPath,如此处的许多答案所示。希望它可以帮助某人。【参考方案5】:

我意识到这个问题已经相当老了(2011 年),但只是为了也发布一个最新的答案,以防有人(比如我)搜索这个问题并偶然发现这个问题:

在 iOS 9 中,Apple 改进了很多 UITableView。为了确保重新加载表格时焦点不会丢失,只需执行以下操作:

tableView.remembersLastFocusedIndexPath = Yes;

它会“神奇地工作”。

更好的是,实施

- (NSIndexPath *)indexPathForPreferredFocusedViewInTableView:(UITableView *)tableView

UITableViewDelegate 中,让表格在第一次绘制到屏幕时知道您希望选择哪一行。

在 iOS 9 之前,我通常只编写自己的 reloadData 方法,获取当前选定的行,重新加载表格,然后再次选择它。在UITableViewController 中,或者如果我需要它来处理无法阻止代码直接调用reloadData 的表,我将UITableView 子类化并覆盖reloadData(嘿,委托是首选方式,但有时你只是必须继承和覆盖,即使在 iOS 中)。

【讨论】:

【参考方案6】:

使用以下代码在表格视图中获取选定的行。 :)

NSArray *selectedRows=[tableView indexPathsForSelectedRows];
        NSMutableArray *rownumberArray=[[NSMutableArray alloc]init];
        for (int i=0; i<selectedRows.count; i++) 
            NSIndexPath *indexPath = [selectedRows objectAtIndex:i];
            NSInteger row = indexPath.row;
            NSNumber *number = [NSNumber numberWithInteger:row];
            [rownumberArray addObject:number];
        

// rownumberArray 包含所选单元格的行号。

【讨论】:

你可以使用for (NSIndexPath *ip in selectedRows) [rowNumberArray addObject: @(ip.row)];来简化这一点

以上是关于UITableView中默认重新加载后如何记住选择的行并维护它们?的主要内容,如果未能解决你的问题,请参考以下文章

ios 分段选择器 数据无法刷新怎么回事啊

在 UITableView (swift2) 中选择单元格时更新/重新加载 ViewController

进行第二次 Json 调用 Swift 3 后如何在 UITableview 中重新加载数据

当我动态更改其框架时,即使重新加载后 UITableView 内容大小也不会更新

iOS:重新加载 UITableView 后滑动显示数据

等到 UITableview 完成重新加载