我有一个非常简单的UITableViewController
子类,用于在单元格中向用户显示字母表中的字符。当用户按下单元格时,将其附属类型设置为复选标记。
#import "MTGTableViewController.h"
@interface MTGTableViewController ()
@property (nonatomic, strong) NSArray *data;
@end
@implementation MTGTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_data = @[@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"N", @"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"W", @"X", @"Y", @"Z"];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _data.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = _data[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
@end
表视图工作正常。我已经在storyboard的原型单元格上设置了我的reuseIdentifier属性,在我开始选择单元格之前,它看起来很好。
问题:当我选择任何单元格时,说"A"单元格,当我向下滚动到它们时,其他尚未可见的单元格也会被选中。更糟糕的是,当我上下滚动时,有时单元格"A"上的复选标记会被移除,并被赋予单元格"B"。
这是因为表视图重用单元格的方式。您需要确保在调用dequeueReusableCellWithIdentifier之后清除附件项。如:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = _data[indexPath.row];
cell.accessoryType = UITableViewCellAccessoryNone;
return cell;
}
尽管——在你做了这个改变之后,你会有一个不同的问题。单元格会因为这个代码而"忘记"它被选中了。因此,您需要更改设置了accessoryType的那一行,以检查单元格是否被选中。
我之前也遇到过这个问题,您需要添加另一个数组来跟踪标记的单元格。只需要创建一个NSIndexPaths的数组这些NSIndexPaths被标记了。有点像:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([arrayOfMarked containsObject:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
迅速3:
我发现一个简化的版本是使用swifts "。indexPathsForSelectedRows"就在"cellForRowAt"函数内。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
//To keep from reusing checkmark in reusableCell
if let selectedIndexPaths = tableView.indexPathsForSelectedRows {
if selectedIndexPaths.contains(indexPath) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
cell.contactsOutlet.text = namesOrganized[indexPath.section].names[indexPath.row]
return cell
}
然后在didSelect和didDeselect中:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell?.accessoryType = UITableViewCellAccessoryType.checkmark
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell?.accessoryType = UITableViewCellAccessoryType.none
}
在didselectRowAtIndex路径上,将索引路径附加到indexpath数组
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if selectedIndexPaths.contains(indexPath) {
let indexOfIndexPath = selectedIndexPaths.indexOf(indexPath)!
selectedIndexPaths.removeAtIndex(indexOfIndexPath)
} else {
selectedIndexPaths += [indexPath]
}
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
然后在cellForRowAtIndexPath上使用selectedIndexpaths Array来检查单元格是否被选中
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let mycell = tableView.dequeueReusableCellWithIdentifier("yourCell", forIndexPath: indexPath) as! YourCustomCell
.
.
.
if selectedIndexPaths.contains(indexPath){
// do what you want to do if the cell is selected
} else {
// do what you want to do if the cell is not selected
}