Кнопка обновления iOS в View Controller Nav: перезагрузка всех tableViewCells, созданных из проанализированного JSON при нажатии - PullRequest
6 голосов
/ 22 декабря 2011

У меня есть довольно важная концептуальная проблема, о которой спрашивали многие люди, но нет легкодоступного четкого ответа, который можно найти при поиске.

Мое приложение простое: несколько строк TableViewCell заполнены данными из проанализированного потока JSON. При щелчке по ячейке информация этой ячейки передается в SecondViewController и отображается. Канал JSON также сохраняется в .plist, а в случае, если Интернет недоступен, TableViewCells заполняются из .plist.

Это все отлично работает.

Тем не менее, последнее, что мне нужно, это кнопка обновления в верхней части моего FirstViewController для обновления канала JSON и всех ячеек в таблице с новыми данными из новых переменных. Однако я столкнулся с проблемой при реализации этого:

Мой исходный вызов JSON и переменные для заполнения ячеек находятся в методе ViewDidLoad. Когда представление загружается, эти переменные устанавливаются и не обновляются. Кроме того, я могу переместить вызов JSON и переменные в viewWillLoad, который будет обновлять таблицу каждый раз после нажатия на ячейку, а затем нажимать «назад» в первом ViewController - это успешно обновит JSON и ячейки, однако это повлияет скорость и делает контроллер представления «паузой» при возвращении к MainViewController, что делает вызов моего исходного JSON и установку моих переменных в viewWillLoad нежизнеспособной опцией.

Я создал кнопку перезагрузки в ViewDidLoad, которая связана с методом IBAction «refresh»:

Создать кнопку программно в ViewDidLoad:

// Reload issues button
UIBarButtonItem *button = [[UIBarButtonItem alloc]
                           initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
                           target:self
                           action:@selector(refresh:)];
self.navigationItem.rightBarButtonItem = button;
[button release];

Метод действия, с которым он связан:

- (IBAction)refresh:(id)sender {

    myRawJson = [[NSString alloc] initWithContentsOfURL:[NSURL  
                                  URLWithString:@"http://www.yoursite.com/json.JSON"]  
                                  encoding:NSUTF8StringEncoding 
                                  error:nil];

    SBJsonParser *parser = [[SBJsonParser alloc] init];
    NSDictionary * myParsedJson = [parser objectWithString:myRawJson error:NULL];

// New updated dictionary built from refreshed JSON
    allLetterContents = [myParsedJson objectForKey:@"nodes"];

// Log the new refreshed JSON
    NSLog(@"You clicked refresh. Your new JSON is %@", myRawJson);

    //Maybe use the notification center?? But don't know how to implement.
    //[[NSNotificationCenter defaultCenter] addObserver:self 
                                            selector:@selector(refreshView:) 
                                            name:@"refreshView" object:nil];
    //[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshView" 
                                            object:nil];

    }

    [self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] 
                     withRowAnimation:UITableViewRowAnimationNone];

    [myRawJson release];
}

В приведенном выше коде вы можете видеть, что я перезваниваю JSON при каждом нажатии кнопки и записываю сообщение на консоль с новым JSON. Это работает. Я даже пересобрал словарь, который успешно добавляет новый контент.

У меня такой вопрос: как я могу заставить tableViewCells «обновляться» и с этими новыми данными? Могу ли я просто заставить кнопку перезагрузить весь контроллер вида, чтобы он снова вызывал ViewDidLoad? Нужно ли переосмыслить структуру моих приложений или переместить исходные переменные из viewDidLoad?

Я читал некоторые сообщения в NSNotificationCenter, но реализация этого все еще сбивает меня с толку, так как я довольно новичок в разработке для iOS.

спасибо ~


Обновление:


Он все еще не обновляется. Вот мой полный код кнопки обновления с [self.tableView reloadData]; позвонил в конце моего IBAction.

    - (IBAction)refresh:(id)sender {
        [DSBezelActivityView newActivityViewForView:        
                         self.navigationController.navigationBar.superview     
                         withLabel:@"Loading Feed..." width:160];

        myRawJson = [[NSString alloc] initWithContentsOfURL:[NSURL 
                     URLWithString:@"http://site.com/mobile.JSON"] 
                     encoding:NSUTF8StringEncoding 
                     error:nil];

        SBJsonParser *parser = [[SBJsonParser alloc] init];
        NSDictionary * myParsedJson = [parser objectWithString:myRawJson error:NULL];
        allLetterContents = [myParsedJson objectForKey:@"nodes"];

        BOOL isEmpty = ([myParsedJson count] == 0);

        if (isEmpty) {
            NSString *refreshErrorMessage = [NSString 
stringWithFormat:@"An internet or network connection is required."];
            UIAlertView *alert = [[UIAlertView alloc] 
                                 initWithTitle:@"Alert" 
                                 message: refreshErrorMessage 
                                 delegate:self 
                                 cancelButtonTitle:@"Close" 
                                 otherButtonTitles:nil];
            [alert show];
            [alert release];

            allLetterContents = [NSMutableDictionary 
                                dictionaryWithContentsOfFile:[self saveFilePath]];
            //NSLog(@"allLetterContents from file: %@", allLetterContents);

        } else {

        NSLog(@"Your new allLetterContents is %@",  allLetterContents);

          // Fast enumeration through the allLetterContents NSMutableDictionary
          for (NSMutableDictionary * key in allLetterContents) {
            NSDictionary *node = [key objectForKey:@"node"];
            NSMutableString *contentTitle = [node objectForKey:@"title"];        
            NSMutableString *contentNid = [node objectForKey:@"nid"];
            NSMutableString *contentBody = [node objectForKey:@"body"];
            // Add each Title and Nid to specific arrays
            //[self.contentTitleArray addObject:contentTitle];
            [self.contentTitleArray addObject:[[contentTitle 
                                     stringByReplacingOccurrencesOfString:@"&" 
                                     withString:@"&"] mutableCopy]];
            [self.contentNidArray addObject:contentNid];
            [self.contentBodyArray addObject:contentBody];
          }

        }

        [self.tableView reloadData];

        [DSBezelActivityView removeViewAnimated:YES];
        [myRawJson release];
    }

Я настраиваю ячейку в cellForRowAtIndexPath ( Обновлено: опубликован весь метод ):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
            cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
        }
    }

    // Configure the cell.
    cell.textLabel.text = [self.contentTitleArray objectAtIndex: [indexPath row]];
    cell.detailTextLabel.text = [self.contentNidArray objectAtIndex: [indexPath row]];
    return cell;
}

Установка его на didSelectRowAtIndexPath:

self.detailViewController.currentNodeTitle = [contentTitleArray 
                                             objectAtIndex:indexPath.row];
self.detailViewController.currentNodeNid= [contentNidArray 
                                          objectAtIndex:indexPath.row];
self.detailViewController.currentNodeBody = [contentBodyArray 
                                            objectAtIndex:indexPath.row];

Так, когда я нажимаю кнопку обновления, таблица должна * обновляться новым json, но не ... Я пропускаю шаг?

enter image description here

Кроме того, это может быть неважно, но я меняю цвета для каждого следующего ряда с помощью:

// Customize the appearance of table view cells.
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row % 2)
    {
        [cell setBackgroundColor:[UIColor colorWithRed:221.0/255.0 green:238.0/255.0 blue:255.0/255.0 alpha:1]];
        cell.textLabel.textColor = [UIColor colorWithRed:2.0/255.0 green:41.0/255.0 blue:117.0/255.0 alpha:1];
        cell.detailTextLabel.textColor = [UIColor colorWithRed:2.0/255.0 green:41.0/255.0 blue:117.0/255.0 alpha:1];

    }    else [cell setBackgroundColor:[UIColor clearColor]];
}

Update

enter image description here

1 Ответ

5 голосов
/ 22 декабря 2011

Вам необходимо вызвать метод перезагрузки.

[self.tableView reloadData];

Это вызовет события dataSource и delegate и обновит UITableView.

Вы можете найти большеинформация в Справочник по классам UITableView :

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

...