我从服务器获取表数据。它是一个JSON数据,每个数组都保存为字典。我有一组JSON对象。
JSON是:
{
sAlbum = Fallen;
sArtist = Evanescence;
sId = 1;
sRate = 3;
stitle = "Everybody's Fool";
},
{
sAlbum = Fallen;
sArtist = Evanescence;
sId = 2;
sRate = 4;
stitle = "Going Under";
}
当我拥有它时(使用AFnetwrking)
[AFJSONRequestOperation JSONRequestOperationWithRequest:request
// The success block runs when (surprise!) the request succeeds.
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
self.musicLibraryArr = [(NSDictionary*)JSON objectForKey:@"array"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"stitle" ascending: YES];
NSArray *sortedArray = [self.musicLibraryArr sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
self.musicLibraryArr = [[NSMutableArray alloc] initWithArray:sortedArray];
self.loadingView.hidden = YES;
// partition
self.tableData = [self partitionObjects:self.musicLibraryArr collationStringSelector:@selector(self)];
NSLog(@"HEADER: %@", self.tableData);
[self.tableView reloadData];
}
现在我调用self.tableData = [self partitionObjects:self.musicLibraryArr collationStringSelector:@selector(self)];为了创建节数组
但我得到的部分是A到Z,在每个部分我都有JSON数据(数据在每个部分都重复,而不是将数据拆分成部分)。
分区方法是:
-(NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector
{ UILocalizedIndexedCollation * collation = [UilocalizedIndexedCollation currentCollation]; NSInteger sectionCount = [[collation sectionTitles] count]; NSMutableArray * unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount];
for (int i = 0; i < sectionCount; i++) {
[unsortedSections addObject:[NSMutableArray array]];
}
for (id object in array) {
NSInteger index = [collation sectionForObject:[object objectForKey:@"sArtist"] collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sArtist" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
for (NSMutableArray *section in unsortedSections) {
NSArray *sortedArray = [section sortedArrayUsingDescriptors:sortDescriptors];
// collationStringSelector:selector]]; [sections addObject:sortedArray]; }
return sections;
}
编辑 - #2 我在这里初始化了数据:
AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:request
// The success block runs when (surprise!) the request succeeds.
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
self.noMusicView.hidden = YES;
//从json数组中获取数据数据 self.musicLibraryArr = [(NSDictionary *)JSON objectForKey:@“array”]; NSLog(@“JSON DATA:%@”,self.musicLibraryArr); //对数组进行排序 NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@“stitle”ascending:YES]; NSArray * sortedArray = [self.musicLibraryArr sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
self.musicLibraryArr = [[NSMutableArray alloc] initWithArray:sortedArray];
self.loadingView.hidden = YES;
self.indexPathController.dataModel = [[TLIndexPathDataModel alloc] initWithItems:self.musicLibraryArr andSectionNameKeyPath:@"sTitle" andIdentifierKeyPath:@"sId"];
// HERE I GET NULL(我检查是否可以在NSLog中看到数据)
NSLog(@"DATA MODEL %@", self.indexPathController.dataModel);
[self.tableView reloadData];
}
// The failure block runs if something goes wrong, such as when the network isn’t available. If that happens, you display an alert view with an error message.
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
// Error view
self.noMusicView.hidden = NO;
self.loadingView.hidden = YES;
self.noMusicViewLabel.text = error.localizedDescription;
}];
可能我在partitionObjects方法中遗漏了一些东西,请帮忙
答案 0 :(得分:0)
您可以使用TLIndexPathTools尝试解决方案here。这种方法使您不必自己操纵传入的数据。您只需提供一系列词典和sectionNameKeyPath
即可。请参阅示例代码。
编辑根据您在下面的评论,我添加了一个示例项目,演示了UIViewController
中嵌入的表视图,其中TLIndexPathTools的依赖性最小。尝试运行Minimal project。视图控制器的来源如下:
#import <UIKit/UIKit.h>
#import "TLIndexPathController.h"
@interface ViewController : UIViewController <TLIndexPathControllerDelegate, UITableViewDataSource>
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@end
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) TLIndexPathController *indexPathController;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.indexPathController = [[TLIndexPathController alloc] initWithItems:@[
@"Chevrolet",
@"Bubble Gum",
@"Chalkboard"]
];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.indexPathController.dataModel.numberOfSections;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.indexPathController.dataModel numberOfRowsInSection:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
NSString *title = [self.indexPathController.dataModel itemAtIndexPath:indexPath];
cell.textLabel.text = title;
return cell;
}
#pragma mark - TLIndexPathControllerDelegate
- (void)controller:(TLIndexPathController *)controller didUpdateDataModel:(TLIndexPathUpdates *)updates
{
[updates performBatchUpdatesOnTableView:self.tableView withRowAnimation:UITableViewRowAnimationFade];
}
@end
以此为基础,您可以配置链接帖子中显示的数据模型。
编辑#2 数据模型配置如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
self.indexPathController = [[TLIndexPathController alloc] init];
//if you get your JSON asynchronously, you would make the request after initializing
//the index path controller, possibly right here. Assuming your JSON request
//passes the result back through a callback block, the block would process
//the incoming array like this block:
^(NSArray *jsonData){
self.indexPathController.dataModel = [[TLIndexPathDataModel alloc] initWithItems:jsonData
andSectionNameKeyPath:@"sTitle"
andIdentifierKeyPath:@"sId"];
};
//or if you already have the data, just set the data model directly:
self.indexPathController.dataModel = [[TLIndexPathDataModel alloc] initWithItems:jsonData
andSectionNameKeyPath:@"sTitle"
andIdentifierKeyPath:@"sId"];
}
如果需要动态更新数据,只需创建一个如上所示的新数据模型,然后再次设置索引路径控制器的dataModel
属性。控制器将调用其controller:didUpdateDataModel
方法,如上面的示例代码所示,代理将在更新对象上调用performBatchUpdatesOnTableView:
,从而使新数据流畅地生成动画。