【问题标题】:Sort UICollectionView by Date按日期对 UICollectionView 进行排序
【发布时间】:2017-01-14 15:07:57
【问题描述】:

我的应用程序包含一个 plist 文件,它是我的 UICollectionView 数据。 plist 如下所示:

这是我的集合视图代码:

-(NSArray *)content {
    if (!_content) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                             NSUserDomainMask,
                                                             YES);
        NSString *plistPath = [[paths lastObject] stringByAppendingPathComponent:@"myJournal.plist"];
        NSDictionary *help = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
        _content = [help allValues];
        _titles = [help allKeys];
        NSLog(@"CONTENT%@", _content);
    }
    return _content;
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
       return [self.content count];
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {


    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateFormat = @"MM/dd/yyyy";
    NSDate *date = [dateFormatter dateFromString:[self.titles objectAtIndex:indexPath.row]];

    dateFormatter.dateFormat=@"MMMM";
    NSString *monthString = [[dateFormatter stringFromDate:date] capitalizedString];

    dateFormatter.dateFormat=@"dd";
    NSString *dayString = [dateFormatter stringFromDate:date];
    static NSString *cellIdentifier = @"cvCell";

    CVCell *cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];


    [cell.labels setText:[[self.content objectAtIndex:indexPath.row] valueForKey:@"verse"]];
    [cell.month setText:monthString];
    [cell.day setText:dayString];

    return cell;
}

以下是视图的外观: 正如你所知道的,这不是我想要的布局方式。我更喜欢从左到右和从上到下的顺序,或者最新的条目优先,但我不能完全明白。关于如何实现这一点的任何建议?

更新:

我添加了一个 NSArray 并使用它首先从 plist 中获取数据,然后使用一个 NSSortDescriptor 来创建 _content 数组。在 NSLog 中,它按我想要的顺序显示,但最终结果没有改变:

-(NSArray *)content {
    if (!_content) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                             NSUserDomainMask,
                                                             YES);
        NSString *plistPath = [[paths lastObject] stringByAppendingPathComponent:@"myJournal.plist"];
        NSDictionary *help = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
        _sortedArray = [help allValues];
        _titles = [help allKeys];


        NSSortDescriptor* nameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"theDate" ascending:NO];
        _content = [_sortedArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:nameSortDescriptor]];
        NSLog(@"%@", _content);
    }
    return _content;
}

【问题讨论】:

    标签: ios objective-c uicollectionview nsarray


    【解决方案1】:

    有两种方法可以做到这一点。一种是设置您的 plist 以在根级别包含数组而不是字典(参见屏幕截图)。这可以确保您保留项目的顺序(字典没有顺序)。

    另一种方法是根据键对项目进行排序。你可以这样做:

    -(NSArray *)content {
        if (!_content) {
            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                                 NSUserDomainMask,
                                                                 YES);
            NSString *plistPath = [[paths lastObject] stringByAppendingPathComponent:@"myJournal.plist"];
            NSDictionary *help = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
            _titles = [help allKeys];
    
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            dateFormatter.dateFormat = @"MM/dd/yyyy";
    
            NSArray *sortedTitles = [_titles sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
    
                NSDate *date1 = [dateFormatter dateFromString:obj1];
                NSDate *date2 = [dateFormatter dateFromString:obj2];
                return [date1 compare:date2];
            }];
    
            _sortedArray = [[NSMutableArray alloc] init];
    
            for (NSString *title in sortedTitles) {
                [_sortedArray addObject:[help objectForKey:title]];
            }
            _content = _sortedArray;
            NSLog(@"%@", _content);
        }
        return _content;
    }
    

    【讨论】:

    • 好的,我已经根据排序描述符的链接更改了代码中的一些内容,请参阅上面的编辑...它仍然根本没有更改顺序。我曾尝试将根目录从字典更改为数组,但这样做完全屏蔽了整个视图。
    • 你在所有包含日期​​的字典中都有'theDate'键吗?
    • 尝试使用我添加到答案中的新代码对其进行排序。
    • 有点像。这样,从左到右,从上到下,我得到: 19 18 17 16 15 14 20 其中 19、16 和 20 是 3 行中每一行的开始。
    • 做到了。我编辑了一些代码以添加到 _sortedArray
    【解决方案2】:

    不要将您的数据存储为字典。字典本质上是无序的集合。使其成为一个字典数组,按日期排序。

    一旦你有一个项目数组,你可以使用以下方法在部分和行中获取它:

    编辑:

    在 Objective-C 中

    NSInteger columns = 3;
    
    NSInteger numberOfSections = (NSInteger) ceil( count/(double)columns));
    
    NSInteger indexOfCell = indexPath.section * columns + indexPath.row;
    

    在斯威夫特中

    let columns  = 3
    
    let numberOfsections = Int(ceil(Double(array.count) / Double(columns)))
    
    let indexOfCell = indexPath.section * columns + indexPath.row
    

    Columns 将是您的集合中的列数。

    numberOfSections 将是您收藏中的部分总数。你会在你的 numberOfSectionsInCollectionView 函数中返回它。

    indexOfCell 会根据请求的部分和行为您提供对象数组的索引。您可以使用它来获取 cellForItemAtIndexPath 函数中的对象。

    或者,您可以将数据存储为字典数组的数组,其中外部数组是您的部分,内部数组是每个部分的行,每个字典都是该单元格的数据。

    【讨论】:

    • 将根目录从字典更改为数组会完全从集合视图中删除所有内容。另外,我对 Swift 不是很熟悉,所以阅读这种语法有点困难。当我对尝试使用 NSSortDescriptor 的代码进行更新时,您可能一直在输入此内容,但它并没有改变任何内容。
    • "将根目录从字典更改为数组会完全删除集合中的所有内容。"然后,您更改的代码中有一个错误。字典不是集合视图或表视图模型的合适结构,因为字典是无序的集合。我输入的代码是用 Swift 编写的(抱歉,我没有注意到你的代码是用 Objective-C 编写的),但概念是一样的。
    • 查看我的答案的编辑。我提供了我的建议的 Objective-C 版本
    猜你喜欢
    • 2020-10-30
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 2014-07-06
    • 1970-01-01
    相关资源
    最近更新 更多