[英]Obj-c - If no search results, return 1 cell in tableview?
[英]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.