Obj-C:如果进行的单元格包含相同的UILabel值,则只返回1个单元格(顶部单元格)?

时间:2017-09-29 06:49:38

标签: ios objective-c uitableview

我的tableview中的前3个单元格中有一个标有“松鼠”字样的标签。有没有办法让它如果一个UILabel在我的桌子上的多个单元格中说“松鼠”,只显示三个中的第一个单元格?

  

例如如果tableviewCell中的UILabel userName等于@“Squirrels”,则只显示一个表   查看包含UILabel中的Squirrels的表格中的单元格

希望这是有道理的。提前谢谢!

编辑:我已成功检索到包含多个常用“名称”值的第一个数组(请参阅下面的代码编辑)。也就是说,当我尝试在我的tableview中显示这些值(firstFoundObject)时,我得到以下崩溃错误:

  

- [__ NSDictionaryI objectAtIndex:]:无法识别的选择器发送到实例0x1c01a5a20 2017-10-03 23:01:51.728128-0700   pawswap [623:85420] ***由于未捕获的异常而终止应用程序   'NSInvalidArgumentException',原因:' - [__ NSDictionaryI   objectAtIndex:]:无法识别的选择器发送到实例0x1c01a5a20'

ViewController.m

- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    NSString *nodeTitle = self.messages[0][@"name"];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", nodeTitle];
    NSArray *filteredArray = [self.messages filteredArrayUsingPredicate:predicate];
    id firstFoundObject = nil;
    firstFoundObject =  filteredArray.count > 0 ? filteredArray.firstObject : nil;

    NSMutableArray *firstObjects = firstFoundObject;

   return [firstObjects count];


}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSString *nodeTitle = self.messages[0][@"name"];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", nodeTitle];
    NSArray *filteredArray = [self.messages filteredArrayUsingPredicate:predicate];
    id firstFoundObject = nil;
    firstFoundObject =  filteredArray.count > 0 ? filteredArray.firstObject : nil;

    NSMutableArray *firstObjects = firstFoundObject;

    static NSString *PointsTableIdentifier = @"MyMessagesCell";

    MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyMessagesCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];


    }




    NSDictionary *receivedSubjectLine = [firstObjects objectAtIndex:indexPath.row];

    NSString *messageSubject = [receivedSubjectLine objectForKey:@"node_title"];


    [cell.subjectLine setText:messageSubject];



    NSDictionary *fromUser = [firstObjects objectAtIndex:indexPath.row];

    NSString *userName = [fromUser objectForKey:@"name"];

    [cell.senderName setText:userName];




    NSDictionary *receivedBody = [firstObjects objectAtIndex:indexPath.row];

    NSString *messageBody = [receivedBody objectForKey:@"body"];

    [cell.fullMessage setText:messageBody];




    NSDictionary *messageReceived = [firstObjects objectAtIndex:indexPath.row];

    NSString *timeReceived = [messageReceived objectForKey:@"published at"];

    NSLog(@"Message Received at %@", timeReceived);

    [cell.receivedStamp setText:timeReceived];




    return cell;

}

PREVIOUS

ViewController.m

#pragma mark - Table view data source

- (int)numberOfSectionsInTableView: (UITableView *)tableview
{
    return 1;
}

- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
   return [self.messages count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *PointsTableIdentifier = @"MyMessagesCell";

    MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyMessagesCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

    NSDictionary *receivedSubjectLine = [self.messages objectAtIndex:indexPath.row];
    NSString *messageSubject = [receivedSubjectLine objectForKey:@"node_title"];
    [cell.subjectLine setText:messageSubject];

    NSDictionary *fromUser = [self.messages objectAtIndex:indexPath.row];
    NSString *userName = [fromUser objectForKey:@"name"];
    [cell.senderName setText:userName];

    NSDictionary *receivedBody = [self.messages objectAtIndex:indexPath.row];
    NSString *messageBody = [receivedBody objectForKey:@"body"];
    [cell.fullMessage setText:messageBody];

    NSDictionary *messageReceived = [self.messages objectAtIndex:indexPath.row];
    NSString *timeReceived = [messageReceived objectForKey:@"published at"];
    [cell.receivedStamp setText:timeReceived];

    return cell;
}

3 个答案:

答案 0 :(得分:1)

是的,你可以轻松地做到, 您将在运行tableView之前执行此操作, 例如:

- (void)viewDidLoad 
{

[super viewDidLoad];


    NSMutableDictionary* NameDictionary=[[NSMutableDictionary alloc] init];

    NSString* PreviousName;

    int oneTime=0;

    for(int i=0;i<[self.messages count];i++){

        NSDictionary *fromUser = [self.messages objectAtIndex: i];

        NSString *userName = [fromUser objectForKey:@"name"];

        if(oneTime==0)
        {

            PreviousName=userName;

            [NameDictionary addObject:[self.messages objectAtIndex: i]];

            oneTime=1;
        }

        if(oneTime!=0)
        {

            if([PreviousName isEqualToString: userName])
            {

            }

            else{

                [NameDictionary addObject:[self.messages objectAtIndex: i]];

            }

            PreviousName=userName;
        }
    }
}

答案 1 :(得分:1)

基本上你遇到的问题是由于firstObject是Dictionary类型,你输入的类型为NSMutableArray。请查看以下行:

  

id firstFoundObject = nil; firstFoundObject = filteredArray.count&gt; 0   ? filteredArray.firstObject:nil;

如果您在应用程序中看到filterArray.firstObject为Dictionary,您在firstFoundObject中捕获但稍后在此处输入NSMutableArray:

  

NSMutableArray * firstObjects = firstFoundObject;

以后当你试图到达这里时,它会崩溃

  

NSDictionary * receivedSubjectLine = [firstObjects   objectAtIndex:indexPath.row];

代码的正确 - 基本版本应该看起来像

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

 static NSString *PointsTableIdentifier = @"MyMessagesCell";
MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier];
if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyMessagesCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];
}

[cell.subjectLine setText:[self.recvMessage objectForKey:@"node_title"]];
[cell.senderName setText:[self.recvMessage objectForKey:@"name"]];
[cell.fullMessage setText:[self.recvMessage objectForKey:@"body"]];
[cell.receivedStamp setText:[self.recvMessage objectForKey:@"published at"]];

return cell;        
} 

虽然它没有经过优化,但它仍然适合你。

COUNT ISSUE:

  

NSMutableDictionary * firstObjects = firstFoundObject;
      return [firstObjects count];

在上面的代码中,你有 numberOfRowsInSection ,因为你有firstFoundObject作为字典所以当你调用[firstObjects count]这是一个有效的调用并且它返回字典中的键数时。

您可以修改它:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{

     NSInteger rowCount = filteredArray.count;
self.recvMessage = rowCount? filteredArray.firstObject: nil;
return rowCount? 1: 0;

}

并且您有新数据实际存储过滤后的对象。

@property (nonatomic) NSDictionary  *recvMessage;

希望这会有所帮助。

答案 2 :(得分:0)

当您要求过滤出senderName属性等于@&#34; Squirrels&#34;的单元格时,您有效地要求在设置后更改数据源。这将导致numberOfRowsInSection方法出现问题,如果在设置数据源之后进行任何过滤,则会返回比您需要的更多的行。

正如您的回答中的一条评论所暗示的那样,&#34;制作一个包含self.messages的独特元素并使用此数组的辅助数组。&#34;构成tableview数据源的数组不需要过滤。 tableview应该能够呈现它。

如果我有足够的声誉对上述答案发表评论,我会说你是对的,因为自我消息没有改变,所以它不起作用。而不是收集&#34;非重复&#34;在NameDictionary中的对象,考虑在NSMutableArray中收集它们。这个新的过滤数组应该是数组的数据源。您可能希望在此ViewController之外过滤此数组,以便一旦数组到达此视图控制器,就可以将其分配给self.messages。

如果您希望排除所有重复项,而不是仅显示彼此相邻的重复项,请考虑此answer