为什么我的tableview只显示日期升序,而不显示其他数据



嗨,我做了一个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...

最新更新