UITableView选中的单元格在滚动时不会保持选定状态

滚动表格时,表格视图单元格不能保持其“选定”状态。 这是相关的代码:

@property (nonatomic, strong) NSIndexPath *selectedIndexPath; -(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.selectedIndexPath = indexPath; //do other stuff } -(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MyCustomCell_iPhone* cell = [tableView dequeueReusableCellWithIdentifier:@"MyCustomCell_iPhone"]; if (cell == nil) cell = [[[NSBundle mainBundle] loadNibNamed:@"MyCustomCell_iPhone" owner:self options:nil] objectAtIndex:0]; if ([indexPath compare: self.selectedIndexPath] == NSOrderedSame) { [cell setSelected:YES animated:NO]; } return cell; } 

对于细胞:

 - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; if (selected) { self.selectedBg.hidden = NO; }else{ self.selectedBg.hidden = YES; } } - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { [super setHighlighted:highlighted animated:animated]; if (highlighted) { self.selectedBg.hidden = NO; }else{ self.selectedBg.hidden = YES; } } 

我怎样才能让选定的单元格保持突出显示? 如果我把它从屏幕上滚动出来,当它在屏幕上滚动时,它会以未选中的状态出现(其selectedBg被隐藏)。

编辑:从单元格中删除setHighlighted方法修复该问题。 但是,这意味着当按下表格单元格时,我不会看到突出显示的状态。 我想知道这个解决scheme。

有同样的问题,select单元格的accessoryView滚动消失。 我的同事发现这个问题非常黑客。 原因是在iOS 7上的touchesBegan事件UITableView取消select单元格,并select触及单元格。 在iOS 6中,它不会发生,滚动选定的单元格保持选中状态。 要在iOS 7中获得相同的行为,请尝试:

1)在你的tableView中启用多项select。

2)转到tableView委托方法didSelectRowAtIndexPath ,并取消选中与代码触及的单元格:

  NSArray *selectedRows = [tableView indexPathsForSelectedRows]; for(NSIndexPath *i in selectedRows) { if(![i isEqual:indexPath]) { [tableView deselectRowAtIndexPath:i animated:NO]; } } 

解决了我的问题! 希望这将是有益的,对我可怜的英语顺便抱歉。

我知道我的方法不是很正统,但似乎工作。 这是我的解决scheme:

 func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if cell.selected { cell.selected = true } else { cell.selected = false } } 

您必须实现您在post中提到的所有方法(@soleil)

滚动开始时,iOS 7/8都取消select单元格(如Alexander Larionov指出的那样)。

对我来说更简单的解决scheme是在我的ViewController中实现这个UIScrollViewDelegate方法:

  - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { NSInteger theRow = [self currentRowIndex]; // my own method NSIndexPath *theIndexPath = [NSIndexPath indexPathForRow:theRow inSection:0]; [self.myTableView selectRowAtIndexPath:theIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; } 

这是因为我的viewController是UITableView的委托,UITableViewinheritance自UIScrollView。

如果你想在Swift中实现同样的function,那么这里是代码。 顺便说一句,我用Swift 2.1使用Xcode 7.2。

 override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if cell.selected == true{ cell.selected = true cell.backgroundColor = UIColor.blackColor() }else{ cell.backgroundColor = tableViewCellColor //Don't panic its my own custom color created for the table cells. cell.selected = false } } 

做其他定制什么你想要..

谢谢..

希望这有助于。

我正在使用Xcode 9.0.1和Swift 4.0。 我发现下面的代码解决了我的select标记,当细胞closures屏幕和返回:

 override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if cell.isSelected { cell.accessoryType = .checkmark } else { cell.accessoryType = .none } } 

您是否尝试过比较索引path的行而不是整个索引path对象?

 if ((indexPath.row == self.selectedIndexPath.row) && (indexPath.section == self.selectedIndexPath.section)) { [cell setSelected:YES animated:NO]; } 

这是我提出的解决scheme – 甚至不觉得哈克。

1)实现-scrollViewWillBeginDragging:-scrollViewWillEndDragging:withVelocity:targetContentOffset:在滚动过程中手动高亮所选行的单元格(如果有的话)。

我的样子是这样的:

 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollview { self.scrollViewIsDragging = YES; if( [self.tableView indexPathForSelectedRow] ) { [[self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]] setHighlighted:YES]; } } - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { self.scrollViewIsDragging = NO; if( [self.tableView indexPathForSelectedRow] ) { [[self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]] setHighlighted:NO]; } } 

scrollViewIsDragging属性是在那里,所以在-tableView:cellForRowAtIndexPath:我们可以确保任何新出队的单元格都有适当的突出显示(例如,如果所选行的单元格在屏幕后滚动到屏幕上)。 该方法的相关部分如下所示:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // ... cell creation/configuration ... if( self.scrollViewIsDragging && [[tableView indexPathForSelectedRow] isEqual:indexPath]) { [cell setHighlighted:YES animated:NO]; } 

}

…在那里,你有它。 selectedRow的单元格将在滚动期间保持突出显示。

UITableViewCell有一个BOOL属性“ selected ”。 无论何时加载单元格,请检查所选状态,并在cellForRowAtIndexPath定义中进行相应的select或取消select,如下所示:

 if (cell.selected) { // Maintain selected state } else{ // Maintain deselected state } 

在这里发布一个简单的答案: https : //stackoverflow.com/a/35605984/3754003

在这里,我也解释了为什么会发生这种情况。

Swift 3解决scheme,2017。

我用这个简单的代码行解决了这个问题:

 cell.isSelected = tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false 

tableView(tableView:cellForRowAt indexPath 🙂方法里面:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // Dequeue a reusable cell if let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID") { cell.isSelected = tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false // Now you can safely use cell.isSelected to configure the cell // ...your configurations here return cell } return UITableViewCell() }