2011-02-08 2 views
0

Я хочу сделать табличное представление, содержащее наши магазины, разделенные городами.Динамические заголовки для разделов в UITableView

Данные для просмотра таблицы собраны через API моего webapp в json-строке, которую я разбираю в NSDictionary, используя рамки Objective-c JSON с открытым исходным кодом.

Ответ выглядит как это:

{ 
city = "Amsterdam"; 
code = erbur; 
title = "Shop Lorem"; 
}, 
{ 
city = "Amsterdam"; 
code = kadap; 
title = "Shop Ipsum"; 
}, 
{ 
city = "Rotterdam"; 
code = elaml; 
title = "Shop Dolor"; 
}, 
{ 
city = "Delft"; 
code = lamla; 
title = "Shop Sit"; 
}, 
{ 
city = "Rotterdam"; 
code = koppa; 
title = "Shop Amet"; 
}, 

Мой первоначальный план был создать один массив за город, хранить эти массивы в словаре и чем, при именовании разделов с titleForHeaderInSection: сделать что-то вроде этого:

if (section == 0) { 
    return @"Amsterdam"; } 
else if (section == 1) { 
    return @"Roteterdam"; 
} Etc.. 

Вот проблема: мы довольно быстро расширяется, и я не хочу обновлять приложение каждый раз мы открываем магазин в новом городе. Поэтому я не могу жестко задавать массивы для городов.

Что было бы правильным способом убедиться, что новые магазины в новых городах отображаются в виде таблицы в нужном городе?

Заранее благодарен!

EDIT Вот мой код:

- (void)getLocData 
    { 

     SBJSON *parser = [[SBJSON alloc] init]; 

     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://foo.bar/locaties/lijst"]]; 
     [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 

     NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 

     NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; 

     NSArray *statuses = [parser objectWithString:json_string error:nil]; 

     //the abive works 

     [statusesArray release]; 
     statusesArray = statuses; 


     NSArray *cityNames = [statuses valueForKey:@"code"]; 


    [locationCodes release]; 
    locationCodes = cityNames; 


    - (void)viewDidLoad { 
     [super viewDidLoad]; 

    [self getLocData]; 

     //titel 
     self.title = NSLocalizedString(@"Locaties", @"Locaties - Steden"); 



    } 
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 

     return [locationCodes count]; 

    } 


    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

     return 1; 

    } 

    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 

     return [locationCodes objectAtIndex:section]; 

    } 


    // Customize the appearance of table view cells. 
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

     static NSString *CellIdentifier = @"Cell"; 

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
     } 

     // Configure the cell... 




     NSString *cityName = [locationCodes objectAtIndex:[indexPath section]]; 
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"code like %@", cityName]; 

     NSArray *filteredShops = [statusesArray filteredArrayUsingPredicate:predicate]; 
     NSDictionary *currentShop = [filteredShops objectAtIndex:[indexPath row]]; 

     NSString *cellTitle = [currentShop objectForKey:@"title"]; 

     cell.textlabel.text = cellTitle; 
     return cell; 

    } 
+0

Тема должна быть UITableView, не так ли? –

+0

К сожалению, вы правы. Редактировать .. –

ответ

3

Похоже, что ваши данные оказались массивом словарей. Если это так, вы можете получить массив названий городов следующим образом:

// Assuming you've stored the array in a variable named shops... 
NSArray *cityNames = [shops valueForKey:@"city"]; 

Так что ваша tableView:numberOfSections: реализации может просто возвращать количество этого массива, а так же tableView:titleForHeaderInSection: может просто вернуть объект в cityNames индексируется номер раздела ,

В tableView:cellForRowAtIndexPath:, можно затем отфильтровать массив, используя экземпляр NSPredicate:

NSString *cityName = [cityNames objectAtIndex:[indexPath section]]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"city like %@", cityName]; 

NSArray *filteredShops = [shops filteredArrayUsingPredicate:predicate]; 
NSDictionary *currentShop = [filteredShops objectAtIndex:[indexPath row]]; 

EDIT

Предполагая, что вы просто хотели, чтобы отобразить название каждого магазина, все, что вы должны были бы это следующие:

NSString *title = [currentShop objectForKey:@"title"]; 
// Assuming you've already obtained the cell... 
[[cell textLabel] setText:title]; 
+0

хорошо здорово! И как я должен установить текст для ячейки в этом примере? –

+0

Хмм, это даст мне исключение из диапазона. Я догадываюсь, что что-то не так с фильтрованием. Любые подсказки? –

+0

Что дает вам исключение диапазона, и что означает сообщение об исключении? Можете быть более конкретными? – jlehr

0

Это у верхней части моей головы, но как только у вас есть данные в NSDictionary вы можете отсортировать его в NSSet и сортировки, что в алфавитном порядке. Предположения:

  • вы перечисляете разделы в алфавитном порядке
  • библиотеки вы ссылаетесь возвращает NSArray из NSDictionaries
  • ключей являются именами, например, "city" "code" "title"

Право данных действительно должно быть NSArray или NSSet объектов NSDictionary. Если это так, то это работает:

NSMutableSet *sectionsSet = [[NSMutableSet alloc] init]; 
for (NSDictionary *item in data) { 
    NSDictionary *aLocation = [[NSDictionary alloc] initWithObjectsAndKeys:[item valueForKey:@"city"],@"city",nil]; 
    [sectionsSet addObject:aLocation]; 
    [aLocation release]; 
} 

NSSortDescriptor *sortAscending = [[NSSortDescriptor alloc] initWithKey:@"city" ascending:YES]; 
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortAscending,nil]; 
NSArray *sortedSections = [[sectionsSet allObjects] sortedArrayUsingDescriptors:sortDescriptors]; 
[sortDescriptors release]; 
[sortAscending release];  

Вышеупомянутый протестирован с помощью фиктивного NSArray NSDictionary. Я думаю, добавив объекты в NSDictionary, вы избегаете создавать свой собственный NSSortDescriptor ..:/Я попытаюсь проверить этот код позже и обновить, если он сломан.

Код titleForHeaderInSection затем будет просто:

возвращение [sortedSections objectAtIndex: раздел];

Увидев, что города теперь отсортированы в алфавитном порядке, вышеуказанный код вернет их в указанном порядке. для примера это дало бы три секции:

0 == Амстердам 1 == Delft 2 == Rotterdam

Самый простой способ получить строку нужно для раздела/клетка вопрос заключается в обеспечении ваш NSArray правильно сортируется в первую очередь.

Конечно, вам нужно было бы изменить код сортировки, чтобы назначить созданные данные для свойства класса, а не локально созданные отсортированные разделы I, используемые в этом примере.

Предостережения:

  • сортировка чувствительны к регистру, нарушения в данных приведет к появлению проблем. Амстердам! = Амстердам! = AMsterdam и т. Д.
+0

Это немного сломано: P Было бы здорово, если бы вы могли проверить, почему. Рядом с этим: я не полностью понимаю это: S. Я как-то понимаю, что вы делаете, но как бы я назвал разделы te 'titleForHeaderInSection:' и как бы убедиться, что правильные магазины отображаются для соответствующих городов с помощью 'cellForRowAtIndexPath:'? –

+0

Да, это было не так. Обновление сейчас! – Diziet

+0

Обновлено для вас, это не совсем понятно из вашего вопроса, но разве вы не имеете дело с NSArray объектов NSDictionary? – Diziet

Смежные вопросы