Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/103.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何使用UICollectionReusableView(使用JSON)对单元格进行分组_Ios_Ruby On Rails_Json - Fatal编程技术网

Ios 如何使用UICollectionReusableView(使用JSON)对单元格进行分组

Ios 如何使用UICollectionReusableView(使用JSON)对单元格进行分组,ios,ruby-on-rails,json,Ios,Ruby On Rails,Json,我正在用Rails应用程序()的JSON填充我的应用程序。我的Rails应用程序中的每一篇帖子都有一个“发布日期”,它们是按发布日期分组的(基本上每周都会发布某些运动鞋)。我希望能够在我的应用程序中做同样的事情,但我很难做到这一点 在我的故事板上,我有一个集合可重用视图,其中包含一个UICollectionReusableView类和一个名为“releasesGroup”的标识符,我还有一个连接到UICollectionReusableView的标签,名为“releasesHeader” 我还想

我正在用Rails应用程序()的JSON填充我的应用程序。我的Rails应用程序中的每一篇帖子都有一个“发布日期”,它们是按发布日期分组的(基本上每周都会发布某些运动鞋)。我希望能够在我的应用程序中做同样的事情,但我很难做到这一点

在我的故事板上,我有一个集合可重用视图,其中包含一个UICollectionReusableView类和一个名为“releasesGroup”的标识符,我还有一个连接到UICollectionReusableView的标签,名为“releasesHeader”

我还想在标题中显示相应的日期,如下所示:

视图控制器

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSURL *upcomingReleaseURL = [NSURL URLWithString:@"http://obscure-lake-7450.herokuapp.com/upcoming.json"];

    NSData *jsonData = [NSData dataWithContentsOfURL:upcomingReleaseURL];

    NSError *error = nil;

    NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];

    self.upcomingReleases = [NSMutableArray array];

    NSArray *upcomingReleasesArray = [dataDictionary objectForKey:@"upcoming_releases"];

    for (NSDictionary *upcomingReleaseDictionary in upcomingReleasesArray) {
        UpcomingRelease *upcomingRelease = [UpcomingRelease upcomingReleaseWithName:[upcomingReleaseDictionary objectForKey:@"release_name"]];
        upcomingRelease.release_date = [upcomingReleaseDictionary objectForKey:@"release_date"];
        [self.upcomingReleases addObject:upcomingRelease];
    }

    [self.collectionView registerClass:[UpcomingReleaseCell class] forCellWithReuseIdentifier:@"UpcomingReleaseCell"];
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return [self.upcomingReleases count];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"Cell";

    UpcomingReleaseCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

    UpcomingRelease *upcomingRelease = [self.upcomingReleases objectAtIndex:indexPath.row];

    cell.release_name.text = upcomingRelease.release_name;

    return cell;
}
我的UICollectionReusableView

@interface ReleasesGroup : UICollectionReusableView
@property (weak, nonatomic) IBOutlet UILabel *releasesHeader;
@end


@implementation ReleasesGroup
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}
@end
谢谢

编辑:

我的音乐

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showRelease"])
    {
        NSIndexPath *selectedIndexPath = [[self.collectionView indexPathsForSelectedItems] objectAtIndex:0];
        ReleaseViewController *releaseViewController = [segue destinationViewController];
        releaseViewController.singleRelease = self.upcomingReleases[selectedIndexPath.row];
    }
}
释放ViewController.h

#import <UIKit/UIKit.h>
#import "UpcomingRelease.h"

@interface ReleaseViewController : UIViewController

@property (strong, nonatomic) UpcomingRelease *singleRelease;
@property (weak, nonatomic) IBOutlet UILabel *release_name;
@property (weak, nonatomic) IBOutlet UILabel *release_price;
@property (weak, nonatomic) IBOutlet UILabel *release_colorway;
@property (weak, nonatomic) IBOutlet UILabel *release_date;
@property (weak, nonatomic) IBOutlet UIImageView *thumb;

@end

好吧,看来你错过了很多东西。首先:要按天对发布进行分组,您需要某种日期操作,在viewDidLoad方法中,您需要已经将json数据分组到与发布日期对应的“bucket”中。一旦你有了这个,剩下的就是小菜一碟了。因此,请注意:

首先,在视图控制器中需要一个包含所有数据的属性。比如:

@property (strong, nonatomic) NSDictionary *upReleases;
@property (strong, nonatomic) NSArray *releaseBuckets;
然后,在
viewDidLoad
方法中,您需要填充此字典:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSURL *upcomingReleaseURL = [NSURL URLWithString:@"http://obscure-lake-7450.herokuapp.com/upcoming.json"];

    NSData *jsonData = [NSData dataWithContentsOfURL:upcomingReleaseURL];

    NSError *error = nil;

    NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];

    NSArray *upcomingReleasesArray = [dataDictionary objectForKey:@"upcoming_releases"];

    //This is the dateFormatter we'll need to parse the release dates

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSv"];
    NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
    [dateFormatter setTimeZone:gmt];
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"]]; //A bit of an overkill to avoid bugs on different locales

        //Temp array where we'll store the unsorted bucket dates
    NSMutableArray *buckets = [[NSMutableArray alloc] init];
    NSMutableDictionary *tmpDict = [[NSMutableDictionary alloc] init];

    for (NSDictionary *upcomingReleaseDictionary in upcomingReleasesArray) {

        //We find the release date from the string
        NSDate *releaseDate = [dateFormatter dateFromString:[upcomingReleaseDictionary objectForKey:@"release_date"]];

        //We create a new date that ignores everything that is not the actual day
        //(ignoring stuff like the time of the day)
        NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        NSDateComponents *components =
        [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:releaseDate];

        //This will represent our releases "bucket"
        NSDate *bucket = [gregorian dateFromComponents:components];

        //We get the existing objects in the bucket and update it with the latest addition
        NSMutableArray *releasesInBucket = [tmpDict objectForKey:bucket];           
        if (!releasesInBucket){
            releasesInBucket = [NSMutableArray array];
            [buckets addObject:bucket];
        }

        UpcomingRelease *upcomingRelease = [UpcomingRelease upcomingReleaseWithName:[upcomingReleaseDictionary objectForKey:@"release_name"]];
        upcomingRelease.release_date = [upcomingReleaseDictionary objectForKey:@"release_date"];
        [releasesInBucket addObject:upcomingRelease];
        [tmpDict setObject:releasesInBucket forKey:bucket];
    }

    [buckets sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        NSDate* date1 = obj1;
        NSDate* date2 = obj2;
        //This will sort the dates in ascending order (earlier dates first)
        return [date1 compare:date2];       
        //Use [date2 compare:date1] if you want an descending order
    }];


    self.upReleases = [NSDictionary dictionaryWithDictionary:tmpDict];
    self.releaseBuckets = [NSArray arrayWithArray:buckets];

}
接下来,您需要拥有与发布桶一样多的部分。小菜一碟:

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return [self.releaseBuckets count];
}
每个桶的电池数量与当天发布的产品数量相同:

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return [[self.upReleases objectForKey:self.releaseBuckets[section]] count];
}
然后,您需要为每个部分设置标题(同样,需要进行一点日期操作,以便为标题部分设置正确的格式):

最后,您需要设置单个单元格:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"Cell";

    UpcomingReleaseCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

    UpcomingRelease *upcomingRelease = [self.upReleases objectForKey:self.releaseBuckets[indexPath.section]][indexPath.row];

    cell.release_name.text = upcomingRelease.release_name;

    return cell;
}
整个代码已经过测试,可以正常工作


编辑以包含键的排序数组

我编辑了答案,现在此代码还为您排序发布日期。你不需要付我任何钱,只要接受我正确的答案:)现在这些桶被正确分组,在我点击“鞋”之前,它会带我到一个包含所有信息(名称、价格、发布日期等)的详细视图,但现在我的应用程序不再解析信息,我在每个字段中都会得到“null”。(我更新了答案,以便您可以查看我的destinationViewController)。
-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    ReleasesGroup* releaseGroup = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"releasesGroup" forIndexPath:indexPath];

    //We tell the formatter to produce a date in the format "Name-of-the-month day"
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"MMMM dd"];
    NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
    [dateFormatter setTimeZone:gmt];
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"]];

    //We read the bucket date and feed it to the date formatter
    NSDate* bucketDate = self.releaseBuckets[indexPath.section];

    releaseGroup.releasesHeader.text = [[dateFormatter stringFromDate:bucketDate] uppercaseString];
    return releaseGroup;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"Cell";

    UpcomingReleaseCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

    UpcomingRelease *upcomingRelease = [self.upReleases objectForKey:self.releaseBuckets[indexPath.section]][indexPath.row];

    cell.release_name.text = upcomingRelease.release_name;

    return cell;
}