我在这个奇怪的问题上高低搜索无济于事。我有一个自定义子类UITableViewCell。前后两个视图,当敲击时,单元翻转。这样做是这样的:
- (IBAction)cellFrontTapped:(id)sender {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
if (_cellFlag == 0)
{
_cellFlag = 1;
[UIView transitionFromView:_cellFrontView toView:_cellBackView
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromTop | UIViewAnimationOptionShowHideTransitionViews
completion:NULL];
[self performSelector:@selector(cellBackTapped:) withObject:self afterDelay:15.0];
}
}
- (IBAction)cellBackTapped:(id)sender {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
if (_cellFlag == 1)
{
_cellFlag = 0;
[UIView transitionFromView:_cellBackView toView:_cellFrontView
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromBottom | UIViewAnimationOptionShowHideTransitionViews
completion:NULL];
}
}
只需几个单元格即可正常工作。最多几页值得。但是当我加载一个更大的数据集时,点击一个单元格就会像预期的那样翻转它,但也会翻转其他单元格。
我意识到这是因为dequeueReusableCellWithIdentifier
正在重复使用这些单元格,但我无法破译如何防止它。
我已尝试将其作为一个UIGestureRecognizer
实施。我尝试过像这样使用didSelectRowAtIndexPath
:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyTableViewCell *cell = (MyTableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
if (cell.cellFlag == 0)
{
[cell cellFrontTapped];
}
else
{
[cell cellBackTapped];
}
}
这些都可以正常翻转单元格,但是tap事件总是翻转列表中的其他单元格。我发现的唯一解决方案是不要像dequeueReusableCellWithIdentifier
这样使用:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyTableViewCell"];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
这是我当前的子类实现:
@implementation MyTableViewCell
- (void)awakeFromNib {
// Adding the recognizer here produced the same result
//UIGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cellTapped)];
//tap.delegate = self;
//[self addGestureRecognizer:tap];
_cellFlag = 0;
}
- (void)cellFrontTapped {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
_cellFlag = 1;
[UIView transitionFromView:_cellFrontView toView:_cellBackView
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromTop | UIViewAnimationOptionShowHideTransitionViews
completion:NULL];
[self performSelector:@selector(cellBackTapped) withObject:self afterDelay:15.0];
}
- (void)cellBackTapped {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
_cellFlag = 0;
[UIView transitionFromView:_cellBackView toView:_cellFrontView
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromBottom | UIViewAnimationOptionShowHideTransitionViews
completion:NULL];
}
-(void)cellTapped
{
if (_cellFlag == 0)
{
[self cellFrontTapped];
}
else
{
[self cellBackTapped];
}
}
@end
这是`configureCell:atIndexpath:
- (void)configureCell:(MyTableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath
{
NSManagedObject *t = [[self fetchedResultsController] objectAtIndexPath:indexPath];
//here i set the labels and such
cell.cellBackAmountLabel.text = [t.amount formattedAmount];
//added
if ([self.flippedCellIndexes containsObject:indexPath])
{
[cell.contentView bringSubviewToFront:cell.cellBackView];
}
else
{
[cell.contentView bringSubviewToFront:cell.cellFrontView];
}
}
我很茫然。在我的情况下,不使用dequeueReusableCellWithIdentifier
会对性能产生重大影响。救命啊!
答案 0 :(得分:2)
我建议将您的模型与您的视图分开。这意味着您应该跟踪哪些单元格应该呈现为翻转,而不是单元格本身。假设您在视图控制器中声明了NSArray
(可能是NSMutableArray
,甚至)flippedIndexes
。
如果您的数据集与您说的一样大,那么您可能应该使用稀疏数组而不是NSArray
。使用NSMutableDictionary
可以轻松实现稀疏数组。 NSMutableSet
也可以发挥作用。
当出列单元格时,您可以检查应该翻转哪些单元格,可能是您的configureCell:atIndexPath:
方法。基本上,如果indexPath
显示在您的稀疏数组或设置上,则将单元格渲染为翻转。这意味着删除你在单元格中声明的cellFlag
属性并根据我提到的模型切换其状态。要翻转单元格,请检查给定flippedIndexes
的{{1}}属性并采取相应措施。像这样:
indexPath
这里我假设-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyTableViewCell *cell = (MyTableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
if (![self.flippedIndexes containsObject:indexPath])
{
[cell cellFrontTapped];
[self.flippedIndexes addObject:indexPath];
}
else
{
[cell cellBackTapped];
[self.flippedIndexes removeObject:indexPath];
}
}
属性使用NSMutableSet
。请注意,只有在flippedIndexes
中检查模型时才能正常工作,否则在滚动时你会神奇地清除单元格。
故事的道德是:不要将状态信息存储在排队的单元格中。