Ios 具有多个自定义单元格的uitableview滚动和重用问题

Ios 具有多个自定义单元格的uitableview滚动和重用问题,ios,objective-c,xcode,uitableview,Ios,Objective C,Xcode,Uitableview,我看到这个问题被问了很多,但没有找到一个好的例子来说明我需要什么。无论何处,人们都指定第0行必须是此单元格,第1行必须是该单元格,其他行必须是其他单元格 我需要根据数据来区分我的细胞。假设这就是我的NSMutableArray字典的样子: {( actionContent = "some comment", actionType = "comment", datetime = "some date", whosAction = "some person" ), ( actio

我看到这个问题被问了很多,但没有找到一个好的例子来说明我需要什么。无论何处,人们都指定第0行必须是此单元格,第1行必须是该单元格,其他行必须是其他单元格

我需要根据数据来区分我的细胞。假设这就是我的NSMutableArray字典的样子:

{(
  actionContent = "some comment",
  actionType = "comment",
  datetime = "some date",
  whosAction = "some person"
),
(
  actionContent = "",
  actionType = "like",
  datetime = "some date", 
  whosAction = "another person"
),
(
  actionContent = "blah blah blah mentioned you",
  actionType = "mention",
  datetime = "some date",
  whosAction = "person"
)}
诸如此类,我知道语法可能有点离题。为此,我创建了两个自定义单元格,并在CellForRowatineXpath中运行了一组if语句,以查看要使用哪个单元格。第一个单元格只有一个UITextView,用于表示喜欢,第二个单元格有两个UITextView,用于评论和提及

问题:当我滚动表格时,第二个单元格进入视图,我得到了这个错误(所有UITextView都有点击手势):

FirstCell没有“second”UITextView,因此不应该有任何second Tap…因此很明显,我在cellForRowAtIndexPath中使用的多个单元格是错误的。我现在将显示我的代码:

第一单元:

self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
    UITextView *first = [[UITextView alloc]initWithFrame:CGRectMake(55, 15, 250, 20)];
    [first setFont:[UIFont systemFontOfSize:10]];
    [first setTextColor:[UIColor blueColor]];
    [first setEditable:NO];
    [first setScrollEnabled:NO];
    [first setSelectable:YES];
    [first setUserInteractionEnabled:YES];
    [first setAllowsEditingTextAttributes:YES];
    first.textContainerInset = UIEdgeInsetsMake(3, 0, 0, 0);
    UITapGestureRecognizer *firstTap = [[UITapGestureRecognizer alloc]init];
    _firstTap = firstTap;
    [first addGestureRecognizer:_firstTap];
    [self addSubview:_first];
}
第二单元:

//same _first UITextView and a second one
    UITextView *first...

    UITextView *second = [[UITextView alloc]initWithFrame:CGRectMake(55, 20, 250, 30)];
    [second setFont:[UIFont systemFontOfSize:10]];
    [second setEditable:NO];
    [second setScrollEnabled:NO];
    [second setSelectable:YES];
    [second setUserInteractionEnabled:YES];
    [second setAllowsEditingTextAttributes:YES];
    second.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
    UITapGestureRecognizer *secondTap = [[UITapGestureRecognizer alloc]init];
    _secondTap = secondTap;
    [second addGestureRecognizer:_secondTap];
    _second = second;
    [self addSubview:_second];
我肯定问题出在这里……CellForRowatineXpath:

static NSString *cellIdentifier = @"cell";
if (myData.count != 0) {
    if ([[[myData objectAtIndex:indexPath.section]valueForKey:@"actionContent"]isEqualToString:@""]) {
        FirstCell *cell = (FirstCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if (!cell) {
            cell = [[FirstCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }
        //run if statements to checks if this is a likes or friend requests
        return cell;
    }else{
        SecondCell *cell = (SecondCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if (!cell){
            cell = [[SecondCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }
        //run if statements to check if comments or mentions
        return cell;
    }
}else{
    //use FirstCell to display empty message
}
return nil;
我希望这不会太长,我希望我说得很清楚。我想我把它们初始化错了。你有什么建议可以让它工作吗


顺便说一句:我用过,但正如我所说,他们已经设置了行,他们知道哪一行应该是哪一个单元格。我需要经常检查。

我认为您的问题在于没有在UITableViewCell子类中重写PrepareForReuse方法

在重用之前,需要清理插入的UITextView。否则,重复使用时会一次又一次地添加它们

就像这样:

-(void)prepareForReuse
{
    [super prepareForReuse];

    [self.first removeFromSuperview];
    self.first = nil;

    [self removeGestureRecognizer:self.firstTap];
    self.firstTap = nil;
}
此外,您的单元格应该有两个不同的标识符。 要执行此操作,必须在实例化tableView后插入这些行:

[self.tableView registerClass:[FirstCell class] forCellWithReuseIdentifier:@"firstCell"];
[self.tableView registerClass:[SecondCell class] forCellWithReuseIdentifier:@"secondCell"];

然后在cellForRow方法中使用这些标识符

我认为您的问题在于没有在UITableViewCell子类中重写PrepareForReuse方法

在重用之前,需要清理插入的UITextView。否则,重复使用时会一次又一次地添加它们

就像这样:

-(void)prepareForReuse
{
    [super prepareForReuse];

    [self.first removeFromSuperview];
    self.first = nil;

    [self removeGestureRecognizer:self.firstTap];
    self.firstTap = nil;
}
此外,您的单元格应该有两个不同的标识符。 要执行此操作,必须在实例化tableView后插入这些行:

[self.tableView registerClass:[FirstCell class] forCellWithReuseIdentifier:@"firstCell"];
[self.tableView registerClass:[SecondCell class] forCellWithReuseIdentifier:@"secondCell"];


然后在cellForRow方法中使用这些标识符

对两种不同的单元格类型使用相同的单元格标识符(“单元格”)。尝试为您的
FirstCell
指定一个类似
@“FirstCell”
的标识符,为您的第二个单元格指定一个类似
@“secondCell”

的标识符。您对两种不同的单元格类型使用了相同的单元格标识符(“单元格”)。请尝试为您的
FirstCell
指定一个类似
@“FirstCell”
的标识符,为您的第二个单元格指定一个类似
@“secondCell”

的标识符,谢谢您的回复。我现在就试试。所以我应该清除两个单元格中的所有内容(第一,第一次点击;第一,第一次点击,第二,第二次点击)?是的,试试这个,让我知道它是如何进行的,然后仍然给我相同的错误。仍然说FirstCell有第二个TAP方法是的,等一下,我写了一个关于这个问题的答案:D因为UITextView只添加了一次(当它们在
initWithStyle:reuseIdentifier:
中创建时),在
prepareForReuse
中删除它们实际上是不正确的。只有在每次在
cellforrowatinexpath:
中添加它们时才合适。不过,关于注册两个不同的重用标识符,您是对的,这是我在回答中遗漏的,所以请投您一票!谢谢你的回复。我现在就试试。所以我应该清除两个单元格中的所有内容(第一,第一次点击;第一,第一次点击,第二,第二次点击)?是的,试试这个,让我知道它是如何进行的,然后仍然给我相同的错误。仍然说FirstCell有第二个TAP方法是的,等一下,我写了一个关于这个问题的答案:D因为UITextView只添加了一次(当它们在
initWithStyle:reuseIdentifier:
中创建时),在
prepareForReuse
中删除它们实际上是不正确的。只有在每次在
cellforrowatinexpath:
中添加它们时才合适。不过,关于注册两个不同的重用标识符,您是对的,这是我在回答中遗漏的,所以请投您一票!看来这已经解决了。我还必须删除prepareforuse,因为当我滚动时,我的手机数据正在消失。添加另一个标识符有效。@denikov是的,只删除
preparefore中的内容使用每次添加到
cellforrowatinexpath:
中的单元格中的内容(实际上不应该这样做)。此外,这与手头的问题并不相关,但为什么不检查
actionType
而不是
actionContent
?你说你需要不同的单元格,这取决于它是提及、喜欢还是评论,那么为什么不检查它的值呢?只是一个建议。很高兴我能帮忙!我想我也可以这样做,但是我必须多次声明细胞。如果actionContent为空,这意味着它只能是喜欢/接受的朋友/不喜欢的朋友,因此它是第一个单元格。如果有actionContent,那么它只能是评论/提及,所以SecondCell。这样我只需要申报一次细胞。@denikov啊,好吧,我明白了。所以不仅仅是喜欢、评论和提及,所以你需要另一种方法来识别它们。有道理。不管怎样,希望我不是太爱管闲事,祝你的应用程序好运!没问题。我应该说得更清楚些。很高兴听取建议…仍在学习。再次谢谢你这样的书修复了它。我还必须删除prepareforuse,因为当我滚动时,我的手机数据正在消失。添加另一个标识符有效。@denikov是的,只删除
preparefore中的内容使用每次添加到
cellforrowatinexpath:
中的单元格中的内容(实际上不应该这样做)。而且,这不是