我已经为我的UITableViewCell创建了一个CheckBoxView控件。我面临的问题是,一旦我选中最上面一行之一并滚动相同的选中标记,就可以在最下面一行看到。这是因为可取消队列的行功能,我想知道如何解决它。这是实现。
CheckBoxView.m:
-(instancetype) initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
[self setup];
[self registerGesturesRecognizers];
return self;
}
-(void) registerGesturesRecognizers {
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(checkBoxTapped:)];
[self addGestureRecognizer:tapGestureRecognizer];
}
-(void) checkBoxTapped:(UITapGestureRecognizer *) recognizer {
if(self.checkBoxViewSelectionChanged) {
if(!self.isChecked) {
self.checkBoxViewSelectionChanged(self,self.isChecked);
self.isChecked = YES;
}
else {
self.checkBoxViewSelectionChanged(self,self.isChecked);
}
}
}
-(void) check {
[_checkBoxImageView setImage:[UIImage imageNamed:@"small-check"]];
}
-(void) uncheck {
_checkBoxImageView.image = nil;
}
-(void) setup {
self.userInteractionEnabled = YES;
self.layer.borderWidth = 0.5f;
self.layer.borderColor = [UIColor lightGrayColor].CGColor;
_checkBoxImageView = [[UIImageView alloc] initWithFrame:CGRectMake(1, 0, 23, 23)];
[self addSubview:_checkBoxImageView];
}
这是cellForRowAtIndexPath方法:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SamplesTableViewCell *cell = (SamplesTableViewCell *) [tableView dequeueReusableCellWithIdentifier:@"SamplesTableViewCell" forIndexPath:indexPath];
Item *sample = [_samples objectAtIndex:[indexPath row]];
cell.productNameLabel.text = sample.product.name;
cell.productColorLabel.text = sample.productColor.name;
[cell.productImageView setImage:sample.productColor.image];
cell.checkboxView.checkBoxViewSelectionChanged = ^(CheckBoxView *checkBoxView, BOOL isChecked) {
if(!isChecked) {
[checkBoxView check];
checkBoxView.isChecked = YES;
}
else {
[checkBoxView uncheck];
checkBoxView.isChecked = NO;
}
};
return cell;
}
CheckBoxView实际上是Storyboard原型单元上的UIView,其类设置为CheckBoxView,因此不会在cellForRowAtIndexPath事件中动态创建它。当我运行上面的代码并选中最上面的行并滚动时,相同的选中标志出现在下面的行中。
更新:
这是我更新的代码,但仍会检查和取消选中底部的行。
cell.checkboxView.checkBoxViewSelectionChanged = ^{
if(!sample.isSelected) {
[sample setSelected:YES];
[cell.checkboxView check];
}
else
{
[sample setSelected:NO];
[cell.checkboxView uncheck];
}
};
最佳答案
您的UIView
不应保持复选框的isChecked
状态。正如您所指出的,由于单元重用,因此将检查所有其他单元,因为正在使用相同的UIView
。
为数据提供支持的模型对象需要维护状态,或者是控制器。
例如:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SamplesTableViewCell *cell = (SamplesTableViewCell *) [tableView dequeueReusableCellWithIdentifier:@"SamplesTableViewCell" forIndexPath:indexPath];
// Some code...
if ([self.myDatasource[indexPath.row] isChecked]) {
cell.checkBoxView.isChecked = YES;
}
return cell;
}
只是一些粗糙的伪代码,但希望您能理解。维持此状态的可能方法是采用模型对象的形式,或者在您的
UIViewController
中有一个NSArray
包含一个NSDictionary
,表示UITableView
中的每一行,其中每个键值对都维护一个特定的UITableViewCell
的状态。