嗨,我做了一个RSS feed应用程序,从多个网站收集feed项目,并在UITableView上发布它们,我试过按日期升序排序结果,目前唯一被排序的是数据和我的数据的其余部分,如'名称'和'描述',并被混乱到随机顺序,而不是与日期对齐。
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
sortDescriptorWithKey:@"pubDate"
ascending:YES];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"EEEE, dd MMM yyyy HH:mm:ss Z"];
NSString *date = [[feeds objectAtIndex:indexPath.row] objectForKey:@"pubDate"];
NSDate *finalDate = [dateFormatter dateFromString:date];
NSLog(@"displayDate = %@", finalDate);
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [feeds
sortedArrayUsingDescriptors:sortDescriptors];
cell.customName.text = [[sortedEventArray objectAtIndex:indexPath.row] objectForKey: @"author"];
cell.customDescription.text = [[sortedEventArray objectAtIndex:indexPath.row] objectForKey: @"description"];
cell.customDate.text = [NSString stringWithFormat:@"%@", finalDate];
(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
element = elementName;
if ([element isEqualToString:@"item"]) {
item = [[NSMutableDictionary alloc] init];
author = [[NSMutableString alloc] init];
description = [[NSMutableString alloc] init];
pubDate = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
}
}
(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:@"author"]) {
[author appendString:string];
} else if ([element isEqualToString:@"link"])
{
[link appendString:string];
} else if ([element isEqualToString:@"description"])
{
[description appendString:string];
}
else if ([element isEqualToString:@"pubDate"])
{
[pubDate appendString:string];
}
}
(void)parserDidEndDocument:(NSXMLParser *)parser {
[self.tableView reloadData];
}
(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"item"]) {
link = [NSMutableString stringWithString:
[link stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
pubDate = [NSMutableString stringWithString:[pubDate stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
[item setObject:author forKey:@"author"];
[item setObject:link forKey:@"link"];
[item setObject:description forKey:@"description"];
[item setObject:pubDate forKey:@"pubDate"];
[feeds addObject:[item copy]];
}
}
根本不应该排序cellForRowAtIndexPath。该方法在表滚动时被反复调用。相反,在xml项完成后将它们插入到正确排序的位置。
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
// your existing code
NSComparator comparator = ^(NSDictionary *a, NSDictionary *b) {
return [a[@"pubDate"] compare:b[@"pubDate"]];
};
NSUinteger index = [feeds indexOfObject:item
inSortedRange:NSMakeRange(0, [feeds count])
options:NSBinarySearchingInsertionIndex
usingComparator:comparator];
[feeds insertObject:[item copy] atIndex:index];
}
不要在cellForRowAtIndexPath中对feeds
进行任何排序或操作。获取项目....
NSDictionary *myModel = feeds[indexPath.row];
// and use it
cell.customName.text = myModel[@"author"];
更少的代码,更少的计算。
编辑
你的日期解释代码很棒,但是放错地方了。通过在cellForRowAtIndexPath
中这样做:它完成了,然后抛出,然后重做,等等。而且,它做得太晚了,在我们需要它的排序中不起作用。
相反,在解析期间构建一个NSDate
,并保留它。排序和任何其他你可能在应用程序的其他地方做的日期计算都需要它。
// first, abstract your (perfectly good) date parse to it's own function
- (NSDate *)dateFromXml:(NSString *)dateString {
// with static declaration, we'll create the date formatter only once
// better than creating a formatter for every date we parse
static NSDateFormatter *df;
if (!df) {
df = [[NSDateFormatter alloc]init];
[df setDateFormat:@"EEEE, dd MMM yyyy HH:mm:ss Z"];
}
return [df dateFromString: dateString];
}
现在,让我们将NSDate表示添加到已解析的xml中。从现在开始,pubDate仅用于显示,我们将添加另一个名为pubDateObj的键来执行任何日期计算,例如排序:
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
// your existing code
// now add the new pubDateObj to the parse
item[@"pubDateObj"] = [self dateFromXml:item[@"pubDate"]];
// the sort code I suggest above, except:
NSComparator comparator = ^(NSDictionary *a, NSDictionary *b) {
return [a[@"pubDateObj"] compare:b[@"pubDateObj"]];
};
// and so on as before
}
您从未排序的feeds
数组中设置date
变量,但从排序的sortedEventArray
数组中获取其他数据。
NSString *date = [[feeds objectAtIndex:indexPath.row] objectForKey:@"pubDate"];
NSDate *finalDate = [dateFormatter dateFromString:date];
然后在构建排序数组之后:
cell.customName.text = [[sortedEventArray objectAtIndex:indexPath.row] objectForKey: @"author"];
cell.customDescription.text = [[sortedEventArray objectAtIndex:indexPath.row] objectForKey: @"description"];
cell.customDate.text = [NSString stringWithFormat:@"%@", finalDate];
您应该在构建排序数组后移动设置finalDate的两行,如下所示:
NSArray *sortedEventArray = [feeds
sortedArrayUsingDescriptors:sortDescriptors];
// Put the two lines here and access the sorted array:
NSString *date = [[sortedEventArray objectAtIndex:indexPath.row] objectForKey:@"pubDate"];
NSDate *finalDate = [dateFormatter dateFromString:date];
编辑:你可能应该获取数组元素一次,然后在需要的时候使用它:
NSDictionary *cellItem = [sortedEventArray objectAtIndex:indexPath.row];
cell.customName.text = [cellItem objectForKey: @"author"];
cell.customDescription.text = [cellItem objectForKey: @"description"];
// and so on...