您的位置:首页 > 产品设计 > UI/UE

[ios]如何分组具有 UICollectionReusableView (使用 JSON) 的单元格

2015-11-12 17:11 387 查看
我填充一个 Rails 应用程序 (http://obscure-lake-7450.herokuapp.com/upcoming.json) 从 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];
}
}

ReleaseViewController.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

ReleaseViewController.m

#import "ReleaseViewController.h"

@interface ReleaseViewController ()

@end

@implementation ReleaseViewController

@synthesize singleRelease = _singleRelease;
@synthesize release_name = _release_name;
@synthesize release_price = _release_price;
@synthesize release_colorway = _release_colorway;
@synthesize release_date = _release_date;
@synthesize thumb = _thumb;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

NSString *thumbURL = nil;

if ([_singleRelease.images isKindOfClass:[NSArray class]] && [_singleRelease.images count])
thumbURL = [[[[[_singleRelease.images objectAtIndex:0] objectForKey:@"image_file"] objectForKey:@"image_file"] objectForKey:@"medium"] objectForKey:@"url"];

if (thumbURL)
{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:thumbURL]];
UIImage *image = [UIImage imageWithData:imageData];
self.thumb.image = image;
}
else {
self.thumb.image = [UIImage imageNamed:@"cover.png"];
}

self.release_name.text = self.singleRelease.release_name;
self.release_price.text = [NSString stringWithFormat:@"$%@", _singleRelease.release_price];
self.release_colorway.text = self.singleRelease.release_colorway;
self.release_date.text = [NSString stringWithFormat:@"%@", _singleRelease.formattedDate];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

解决方法 1:

好的它会出现您错过了不少事。首先: 要组由天发布,你将需要某种日期操纵,在 viewDidLoad 方法中,你将需要已分组的 json 数据到"水桶"对应的发布日期。一旦您有这,剩下的就一块蛋糕。所以放到它上面:

首先,你需要一个属性在您的视图控制器包含的所有数据。就像这样:

@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];
}

然后,您需要设置每节 (再次,一点点的操纵有必要你页眉节的正确格式的日期) 的标头:

-(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;
}

这整个代码已测试及工程。

编辑要包含已排序的数组的键
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: