繁体   English   中英

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

[英]Obj-C: Only return 1 cell (top cell) if cells proceeding contain the same UILabel values?

我的表格视图中的前3个单元格带有一个标签,上面写着“松鼠”一词。 有没有一种方法可以使UILabel在表中的多个单元格中显示“ Squirrels”,从而仅显示三个单元格中的第一个单元格?

例如,如果tableviewCell中的UILabel userName等于@“ Squirrels”,则在UILabel中仅在包含松鼠的表中显示一个表视图单元格

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


编辑:我已经成功检索了包含多个公共“名称”值的第一个数组(请参见下面的代码编辑)。 也就是说,当我尝试在表格视图中显示这些值(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;

}

以前

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;
}

是的,您可以轻松做到这一点,可以在运行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;
        }
    }
}

基本上,您遇到的问题是由于firstObject属于Dictionary类型,并且您将其类型强制转换为NSMutableArray。 请检查以下行:

id firstFoundObject = nil; firstFoundObject = FilteredArray.count> 0吗? filteredArray.firstObject:无;

如果您看到在应用程序中将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;        
} 

尽管尚未优化,但仍可以为您工作。

计数问题:

NSMutableDictionary * firstObjects = firstFoundObject;
返回[firstObjects计数];

在上面的代码中,由于将firstFoundObject作为字典,因此在numberOfRowsInSection内部,因此,当您调用有效的调用[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;

希望这可以帮助。

当您要求过滤出senderName属性等于@“ Squirrels”的单元格时,实际上是在要求设置数据源后要求更改它。 这将导致您的numberOfRowsInSection方法出现问题,如果在设置数据源之后进行任何过滤,则该方法将返回比您需要的行更多的行。

正如您对答案的评论之一所言,“创建一个包含self.messages唯一元素的辅助数组,并使用该数组。” 组成tableview数据源的数组应该不需要过滤。 tableview应该只能够显示它。

如果我有足够的声誉对上述答案发表评论,那么您说对了,因为self.messages不会改变,这是正确的。 与其在NameDictionary中收集“非重复”对象,不如考虑在NSMutableArray中收集它们。 这个新的,经过过滤的阵列应该是阵列的数据源。 您可能希望在此ViewController之外过滤此数组,以便一旦数组到达此视图控制器,就可以将其分配给self.messages。

如果您要排除所有重复项,而不是仅将彼此相邻的重复项排除在外,请考虑以下答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM