Objective C - UITableViewCell 中的 ImageView(自定义复选标记)在选择多个单元格后停止切换
Objective C - ImageView (custom checkmark) in UITableViewCell stops toggling after multiple cell selections
我在一个简单的列表应用程序 (iOS) 中遇到了 tableViewCells 的一些非常奇怪的行为。
这是我的工作应用程序的基本功能:
具有 2 个部分的 TableView。第一部分(例如 2 个单元格)始终可见。第二部分可以是 shown/hidden,在部分 header 中带有自定义按钮。我创建了两个 类(即 FirstSectionItem 和 SecondSectionItem),它们都带有布尔值 属性 "completed" 和一些其他属性。
编译后应用程序按预期运行。点击单元格会导致显示复选标记,再次点击它们会隐藏复选标记(=自定义图像视图)。但是,在点击一些不同的单元格(随机顺序)或 showing/hiding 第二部分之后,无论我点击多少单元格,复选标记 (ImageViews) 都会保持选中状态。一段时间后,每个单元格都被选中并且无法取消选中,但布尔值仍在不断变化。
部分代码如下:
@property NSMutableArray *sectionTitleArray;
@property NSMutableDictionary *sectionContentDict;
@property NSMutableArray *firstSectionItems;
@property NSMutableArray *secondSectionItems;
ViewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
if (!self.sectionTitleArray) {
self.sectionTitleArray = [NSMutableArray arrayWithObjects:@"section1", @"section2", nil];
}
self.firstSectionItems = [[NSMutableArray alloc] init];
self.secondSectionItems = [[NSMutableArray alloc] init];
[self loadInitialData];
self.sectionContentDict = [[NSMutableDictionary alloc] init];
self.arraySection1 = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.firstSectionItems count]; i++)
{
FirstSectionItem *firstSectionItem = [self.firstSectionItem objectAtIndex:i];
[self.arraySection1 addObject:firstSectionItem.itemName];
}
self.arraySection2 = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.secondSectionItems count]; i++)
{
SecondSectionItem *secondSectionItem = [self.secondSectionItems objectAtIndex:i];
[self.arrayFuture addObject:secondSectionItem.itemName];
}
[self.sectionContentDict setValue:self.arraySection1 forKey:[self.sectionTitleArray objectAtIndex:0]];
[self.sectionContentDict setValue:self.arraySection2 forKey:[self.sectionTitleArray objectAtIndex:1]];
}
CellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ListPrototypeCell" forIndexPath:indexPath];
// ... cell content ...
NSArray *content = [self.sectionContentDict valueForKey:[self.sectionTitleArray objectAtIndex:indexPath.section]];
//... constraints ...
UIImage *checkmark = [UIImage imageNamed:@"checkmark.png"];
UIImage *noCheckmark = [UIImage imageNamed:@"transparent.png"];
UIImageView *imageView = [[UIImageView alloc] init];
if (indexPath.section==0){
FirstSectionItem *firstSectionItem = [self.firstSectionItems objectAtIndex:indexPath.row];
imageView.image = firstSectionItem.completed ? checkmark : noCheckmark;
}
if (indexPath.section==1){
if(self.sec2isTapped == YES){
SecondSectionItem *secondSectionItem = [self.secondSectionItems objectAtIndex:indexPath.row];
imageView.image = secondSectionItem.completed ? checkmark : noCheckmark;
}
}
[cell.contentView addSubview:imageView];
// ... more constraints
return cell;
}
didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
if (indexPath.section ==0){
FirstSectionItem *tappedItem = [self.firstSectionItems objectAtIndex:indexPath.row];
tappedItem.completed = !tappedItem.completed;
}
if (indexPath.section ==1){
SecondSectionItem *tappedItem = [self.secondSectionItems objectAtIndex:indexPath.row];
tappedItem.completed = !tappedItem.completed;
}
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationMiddle];
[tableView endUpdates];
}
我尝试了多种方法,但其中 none 似乎有效。我不知道是什么问题。
(我是 objective C 的新手,所以有些部分可能看起来有点不对劲)。
提前致谢。
问题是每次 cellForRowAtIndexPath 为 运行 时您都在初始化 UIImageView。但请记住,单元格是重复使用的,所以您正在做的是重复使用带有复选标记的单元格,并在顶部添加一个新的清除复选标记。
您需要做的是:
- 在故事板中添加 imageView,对其进行标记,然后使用该标记在代码中找到它
- 子类化 UITableViewCell 并在其中分配正确的图像。
网上有很多关于如何做到这两点的文章。
我在一个简单的列表应用程序 (iOS) 中遇到了 tableViewCells 的一些非常奇怪的行为。
这是我的工作应用程序的基本功能:
具有 2 个部分的 TableView。第一部分(例如 2 个单元格)始终可见。第二部分可以是 shown/hidden,在部分 header 中带有自定义按钮。我创建了两个 类(即 FirstSectionItem 和 SecondSectionItem),它们都带有布尔值 属性 "completed" 和一些其他属性。
编译后应用程序按预期运行。点击单元格会导致显示复选标记,再次点击它们会隐藏复选标记(=自定义图像视图)。但是,在点击一些不同的单元格(随机顺序)或 showing/hiding 第二部分之后,无论我点击多少单元格,复选标记 (ImageViews) 都会保持选中状态。一段时间后,每个单元格都被选中并且无法取消选中,但布尔值仍在不断变化。
部分代码如下:
@property NSMutableArray *sectionTitleArray;
@property NSMutableDictionary *sectionContentDict;
@property NSMutableArray *firstSectionItems;
@property NSMutableArray *secondSectionItems;
ViewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
if (!self.sectionTitleArray) {
self.sectionTitleArray = [NSMutableArray arrayWithObjects:@"section1", @"section2", nil];
}
self.firstSectionItems = [[NSMutableArray alloc] init];
self.secondSectionItems = [[NSMutableArray alloc] init];
[self loadInitialData];
self.sectionContentDict = [[NSMutableDictionary alloc] init];
self.arraySection1 = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.firstSectionItems count]; i++)
{
FirstSectionItem *firstSectionItem = [self.firstSectionItem objectAtIndex:i];
[self.arraySection1 addObject:firstSectionItem.itemName];
}
self.arraySection2 = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.secondSectionItems count]; i++)
{
SecondSectionItem *secondSectionItem = [self.secondSectionItems objectAtIndex:i];
[self.arrayFuture addObject:secondSectionItem.itemName];
}
[self.sectionContentDict setValue:self.arraySection1 forKey:[self.sectionTitleArray objectAtIndex:0]];
[self.sectionContentDict setValue:self.arraySection2 forKey:[self.sectionTitleArray objectAtIndex:1]];
}
CellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ListPrototypeCell" forIndexPath:indexPath];
// ... cell content ...
NSArray *content = [self.sectionContentDict valueForKey:[self.sectionTitleArray objectAtIndex:indexPath.section]];
//... constraints ...
UIImage *checkmark = [UIImage imageNamed:@"checkmark.png"];
UIImage *noCheckmark = [UIImage imageNamed:@"transparent.png"];
UIImageView *imageView = [[UIImageView alloc] init];
if (indexPath.section==0){
FirstSectionItem *firstSectionItem = [self.firstSectionItems objectAtIndex:indexPath.row];
imageView.image = firstSectionItem.completed ? checkmark : noCheckmark;
}
if (indexPath.section==1){
if(self.sec2isTapped == YES){
SecondSectionItem *secondSectionItem = [self.secondSectionItems objectAtIndex:indexPath.row];
imageView.image = secondSectionItem.completed ? checkmark : noCheckmark;
}
}
[cell.contentView addSubview:imageView];
// ... more constraints
return cell;
}
didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
if (indexPath.section ==0){
FirstSectionItem *tappedItem = [self.firstSectionItems objectAtIndex:indexPath.row];
tappedItem.completed = !tappedItem.completed;
}
if (indexPath.section ==1){
SecondSectionItem *tappedItem = [self.secondSectionItems objectAtIndex:indexPath.row];
tappedItem.completed = !tappedItem.completed;
}
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationMiddle];
[tableView endUpdates];
}
我尝试了多种方法,但其中 none 似乎有效。我不知道是什么问题。
(我是 objective C 的新手,所以有些部分可能看起来有点不对劲)。
提前致谢。
问题是每次 cellForRowAtIndexPath 为 运行 时您都在初始化 UIImageView。但请记住,单元格是重复使用的,所以您正在做的是重复使用带有复选标记的单元格,并在顶部添加一个新的清除复选标记。
您需要做的是:
- 在故事板中添加 imageView,对其进行标记,然后使用该标记在代码中找到它
- 子类化 UITableViewCell 并在其中分配正确的图像。
网上有很多关于如何做到这两点的文章。