die Grundidee ist, dass Wörterbücher ungeordnet sind, so müssen Sie eine Möglichkeit, sie in der richtigen Reihenfolge abzurufen. Ich könnte vorschlagen, ein sortiertes Array der Schlüssel des Wörterbuchs zu erstellen.
// build dictionary of objects, keyed by date
NSMutableDictionary *objectsForDates = ...
// build sorted array of dates in descending order
NSArray *dates = [[objectsForDates allKeys] sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return [obj2 compare:obj1];
}];
Sie können dann dieses dates
Objekt verwenden, um die „Abschnitte“ der Tabelle Ansicht zu vertreten und dass dann, welcher Eintrag im Wörterbuch verwenden zu wissen, zurückzukehren:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.dates count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.objectsForDates[self.dates[section]] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [self.formatter stringFromDate:self.dates[section]];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
Location *object = self.objectsForDates[self.dates[indexPath.section]][indexPath.row];
cell.textLabel.text = object.home;
return cell;
}
Hinweis, Ich würde vorschlagen, einige nicht verwandte Änderungen an Ihrem Code:
Ich würde vorschlagen, einen benutzerdefinierten Objekttyp verwenden e zum Inhalt Ihres JSON. Dies bietet eine stärkere Typisierung als eine einfache NSDictionary
.
Ich würde auch sicherstellen, dass die Typen natürlichen eingegeben (zum Beispiel der id
sieht aus wie es ein NSInteger
sein soll, die date
sieht aus wie es ein NSDate
sein soll).
Ich würde diesem benutzerdefinierten Typ auch einen initWithDictionary
Initialisierer geben, um den Parsing-Code zu vereinfachen.
Die Logik zum Erstellen des Wörterbuchs nach Datum (Ihre convertSectionTableData
) kann ein wenig vereinfacht werden.
Ihr Datumsformatierer für die Benutzeroberfläche sollte locale
von nicht verwenden. Ihr Formatierer, der den JSON analysiert, sollte (oder genauer gesagt, er sollte en_US_POSIX
verwenden), aber wenn Sie das Format in der Benutzeroberfläche präsentieren, sollten Sie das eigene Gebietsschema des Benutzers verwenden.
Ihr Datumsformatierer für die Benutzeroberfläche sollte auch keinen festen dateFormat
String verwenden. Verwenden Sie eines der bereits vorhandenen dateStyle
, oder erstellen Sie eine lokalisierte Version unter Verwendung von dateFormat
dateFormatFromTemplate
.
Wie dem auch sei, die zusammen ziehen, erhalten Sie so etwas wie:
@interface Location : NSObject
@property (nonatomic) NSInteger identifier;
@property (nonatomic, copy) NSString *home;
@property (nonatomic, strong) NSDate *date;
- (instancetype)initWithDictionary:(NSDictionary *)dictionary;
@end
@implementation Location
- (instancetype)initWithDictionary:(NSDictionary *)dictionary {
self = [super init];
if (self) {
self.identifier = [dictionary[@"id"] integerValue];
self.home = dictionary[@"home"];
[self setDateFromString:dictionary[@"date"]];
}
return self;
}
- (void)setDateFromString:(NSString *)string {
static NSDateFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [[NSDateFormatter alloc] init];
formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
formatter.dateFormat = @"yyyy-MM-dd";
});
self.date = [formatter dateFromString:string];
}
@end
Und
@interface ViewController()
@property (nonatomic, strong) NSMutableDictionary *objectsForDates;
@property (nonatomic, strong) NSArray *dates;
@property (nonatomic, strong) NSDateFormatter *formatter;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// set formatter for output
self.formatter = [[NSDateFormatter alloc] init];
[self.formatter setDateFormat:[NSDateFormatter dateFormatFromTemplate:@"EEEdMMMyyyy" options:0 locale:[NSLocale currentLocale]]];
self.formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
// perform request
NSURL *url = [NSURL URLWithString:@"http://borindatabase.000webhostapp.com/jsonData.php"];
[[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error || !data) {
NSLog(@"networkError: %@", error);
return;
}
NSError *parseError;
NSArray *values = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (![values isKindOfClass:[NSArray class]]) {
NSLog(@"parseError: %@", parseError);
}
// build dictionary of objects, keyed by date
NSMutableDictionary *objectsForDates = [[NSMutableDictionary alloc] init];
for (NSDictionary *value in values) {
Location *object = [[Location alloc] initWithDictionary:value];
NSMutableArray *objects = objectsForDates[object.date];
if (!objects) {
objects = [[NSMutableArray alloc] init];
objectsForDates[object.date] = objects;
}
[objects addObject:object];
}
// build sorted array of dates in descending order
NSArray *dates = [[objectsForDates allKeys] sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return [obj2 compare:obj1];
}];
// now update UI
dispatch_async(dispatch_get_main_queue(), ^{
self.objectsForDates = objectsForDates;
self.dates = dates;
[self.tableView reloadData];
});
}] resume];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.dates count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.objectsForDates[self.dates[section]] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [self.formatter stringFromDate:self.dates[section]];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
Location *object = self.objectsForDates[self.dates[indexPath.section]][indexPath.row];
cell.textLabel.text = object.home;
return cell;
}
@end
können Sie Ihr Datenformat hinzufügen? – KKRocks
Was macht Ihr Code derzeit? Ich meine, was funktioniert und was nicht? – Larme
Dies sind die Daten, die ich abrufen möchte: http://borindatabase.000webhostapp.com/jsonData.php Die Daten wurden perfekt abgerufen, aber es wird nicht richtig sortiert. Und ich weiß nicht, wie man das Datum in TitleForHeaderInSection so formatiert: Mo, 3 Jul 2017 –