2013-09-09 3 views
2

У меня есть UITableView, где пользователь нажимает на аксессуар. Аксессуар запускает UIView в модальном виде (с использованием presentViewController).Обновление UITableView работает только при перемещении таблицы?

Когда он возвращается, он предназначен для обновления ячейки tableview с требуемыми данными.

В настоящее время я использую Singleton для захвата userData внутри словаря; но даже если я использую NSNotification, у меня такая же проблема.

Моя проблема заключается в том, что когда модальный диалог отклоняется, табличное представление никогда не обновляется; однако , если я прокручиваю или иным образом физически перемещаю затем таблицу, запись в ячейке обновляется.

Я получаю те же результаты, если попытаюсь перезагрузить ячейку или весь стол с помощью NSNotifications.

Мне интересно, смогу ли я помочь в этом; как я могу перезагрузить ячейку?

Код, относящийся к отображению ячеек и способу представления модальности ниже;

Примечания;

_eventName is just a NSString

-(void) viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 

    if ([[MySingleton sharedInstance].userData objectForKey:@"eventName"] !=nil) { 
     _eventName = [[MySingleton sharedInstance].userData objectForKey:@"eventName"]; 
    } 
} 

// Customize the appearance of table view cells. 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 

    NSDictionary *dict; 
    NSString *name; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
     cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 

    dict = [_template objectAtIndex:indexPath.row]; 
    name = [dict objectForKey:@"name"]; 

    cell.textLabel.text = name; 

    NSString *key = [[dict objectForKey:@"key"] lowercaseString]; 

    if ([[key lowercaseString] isEqualToString:@"name"]==YES) { 
     cell.detailTextLabel.text = _eventName; 
    } 



    return cell; 
} 



-(void) tableView:(UITableView *)tv accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath 
{ 
    NSDictionary *dict = [_template objectAtIndex:indexPath.row]; 
    NSString *key = [[dict objectForKey:@"key"] lowercaseString]; 

    NSString *name = @""; 

    if ([key isEqualToString:@"name"]==YES) { 

     EventNameVC *nameEditor = [[EventNameVC alloc] initWithNibName:@"EventNameVC" bundle:nil]; 

     if (_eventName !=nil) { 
      nameEditor.txtName.text = _eventName; 
     } else { 
      nameEditor.txtName.text = name; 
     } 

     UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:nameEditor]; 


// When we return from the view, reload the cell. 
     [self presentViewController:nav animated:YES completion:^{ 

      [self.tv reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight]; 

     }]; 

     nav = nil; 
    } 

} 

Edit: Пытались использовать уведомления для обнаружения закрытия модального в; но у меня все еще есть одна и та же проблема, то есть UITableView отображает только обновленные данные, когда я физически перемещаю таблицу.

На мой взгляд, контроллер я это делаю;

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

     NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; 

     self.notificationObserver = [[NSNotificationCenter defaultCenter] 
            addObserverForName:@"dismissModalView" 
            object:nil 
            queue:mainQueue 
            usingBlock:^(NSNotification *notification) { 
             NSLog(@"Notification received!"); 

             NSDictionary *userInfo = notification.userInfo; 
             _eventName = [userInfo objectForKey:@"eventName"]; 

             NSLog(@"received._eventName = %@", _eventName); 

             [self performSelectorOnMainThread:@selector(updateTable) withObject:nil waitUntilDone:YES]; 
            }]; 

    } 
    return self; 
} 

-(void) updateTable { 
NSLog(@"%s", __PRETTY_FUNCTION__); 
[self.tv reloadData]; 
} 

я запускаю мой modalView внутри accessoryButtonTappedForRowWithIndexPath метода

EventNameVC *nameEditor = [[EventNameVC alloc] initWithNibName:@"EventNameVC" bundle:nil]; 
     UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:nameEditor]; 
     [self presentViewController:nav animated:YES completion:nil]; 

Итак, когда мы начинаем модальное представление с использованием presentViewController и об увольнении, уведомление обжигают.

В моем модального зрении

-(IBAction) btnSave:(id)sender { 
    [self.txtName resignFirstResponder]; 

    ///[[MySingleton sharedInstance].userData setObject:self.txtName.text forKey:@"eventName"]; 
    NSDictionary *userInfo = [NSDictionary dictionaryWithObject:self.txtName.text forKey:@"eventName"]; 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"dismissModalView" object:self userInfo:userInfo]; 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

Когда я запускаю это, updateTable правильно выстрелил и вошел в консоли.

Пока все хорошо.

Но табличное представление все еще не обновило его данные; Мне все же приходится физически перемещать таблицу, чтобы сделать обновление ячейки.

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

+0

Попробуйте вызвать 'reloadData' в представлении таблицы, чтобы заставить его обновиться. –

+0

Когда вы говорите, поместите reloadData в tableView, в каком методе? Вы имеете в виду в блоке завершения '[self presentViewController: nav animated: YES complete ..." или в другом месте? – zardon

+0

Я попытался поместить reloadData внутри 'viewWillAppear ', например' [self.tv reloadData]; 'это не приводит к корректному отображению ячейки. – zardon

ответ

0

Проблема в том, что вы вызываете – reloadRowsAtIndexPaths:withRowAnimation:, когда вы представляете контроллер вида (nav). Блок «завершения» запускается, когда ОС завершается, отображая контроллер вида (не когда представление возвращается, как вы его помещаете) и, следовательно, видимо для пользователя.

Попробуйте позвонить – reloadRowsAtIndexPaths:withRowAnimation:, когда вы упустите контроллер вида.Это может пойти в блок «завершения» – dismissViewControllerAnimated:completion:

Надеюсь, это поможет!

UPDATE:

Привет Кардиган; Я видел ваш обновленный вопрос и позвольте мне сказать вам, если метод updateTable получает правильное имя после увольнения контроллера EventNameVC, это означает, что проблема находится где-то в другом месте. Вызов reloadData в вашем представлении таблицы заставит его обновить содержимое с любыми изменениями, внесенными вами в базовый источник данных, если ... источник данных не был обновлен к моменту звонка reloadData.

Глядя на ваш метод – tableView:cellForRowAtIndexPath: я вижу, что вы получите информацию для ваших клеток из этих двух строк кода:

dict = [_template objectAtIndex:indexPath.row]; 
name = [dict objectForKey:@"name"]; 

информация поступает из _template массива. Теперь, в вашем модальном представлении у вас есть свойство textName, которое я предполагаю, это то, что вы хотите в конечном счете отобразить в виде таблицы, не так ли? Когда диспетчер просмотра отклонен, вы отправляете эту информацию внутри словаря с помощью уведомления, но когда вы получаете это уведомление, я не вижу нигде в вашем блоке, где вы добавляете эту информацию в массив _template. Как вы обновляете свой источник данных?

Пожалуйста, попробуйте следующее:

Добавить точку останова в методе updateTable. Когда приложение останавливается на нем, добавьте еще одну точку останова, но на этот раз к методу – tableView:cellForRowAtIndexPath:; который покажет вам, правильно ли работает метод reloadData. Если приложение затем останавливается в – tableView:cellForRowAtIndexPath:, то вы находитесь на правильном пути. В этот момент перейдите к просмотру содержимого источника данных. Вы можете сделать это, набрав po _template (затем нажмите Enter) прямо на консоль XCode. Таким образом, вы сможете увидеть, была ли она обновлена ​​с информацией, которую вы хотите.

Сообщите мне, как это.

+0

Хорошо, я попробую это. Я пытался выяснить, где я ошибся, так что, возможно, это поможет решить его. – zardon

+0

Привет. Я попытался использовать NSNotification для перезагрузки всей таблицы. Он прислушивается к увольнению. Уведомление работает; но таблица по-прежнему отображается неправильно, пока я физически не переместил представление таблицы. Вы упомянули в своем ответе, что я могу использовать 'reloadRows ...' внутри' rejectViewControllerAnimated', но я не уверен, как это сделать. – zardon

+0

Привет, @ кардиган, см. Мой обновленный ответ. – LuisCien

0

Я принял ответ @ LuisCein. Я переписал свой рабочий стол. Сейчас он обновляется;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization   
     self.pTemplate = [[MySingleton sharedInstance] pTemplate]; 

     NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; 

     [[NSNotificationCenter defaultCenter] 
     addObserverForName:@"dismissModalView" 
     object:nil 
     queue:mainQueue 
     usingBlock:^(NSNotification *notification) { 
      NSLog(@"Notification received!"); 

      NSDictionary *userInfo = notification.userInfo; 
      _eventName = [userInfo objectForKey:@"eventName"]; 

      NSLog(@"received._eventName = %@", _eventName); 

      [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; 
     }]; 

    } 
    return self; 
} 

... 

- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section 
{ 
    return pTemplate.count; 
} 


// Customize the appearance of table view cells. 
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
     cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 

    NSDictionary *dict = [self.pTemplate objectAtIndex:indexPath.row]; 
    NSString *name = [dict objectForKey:@"name"]; 

    cell.textLabel.text = name; 
    cell.detailTextLabel.text = @"Detail text"; 

    NSString *key = [[dict objectForKey:@"key"] lowercaseString]; 

    if ([[key lowercaseString] isEqualToString:@"name"]==YES) { 

     if (_eventName !=nil) cell.detailTextLabel.text = _eventName; 
    } 

    if ([[key lowercaseString] isEqualToString:@"date"]==YES) { 
     NSString *dateString = [dateFormater stringFromDate:_eventDate]; 
     if (_eventDate !=nil) cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", dateString]; 
    } 

    if ([[key lowercaseString] isEqualToString:@"venue"]==YES) { 
     if (_venueName != nil) cell.detailTextLabel.text = _venueName; 
    } 

    cell.detailTextLabel.textColor = [UIColor darkGrayColor]; 

    return cell; 
} 

-(void) tableView:(UITableView *)tv accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath 
{ 
    NSDictionary *dict = [self.pTemplate objectAtIndex:indexPath.row]; 
    NSString *key = [[dict objectForKey:@"key"] lowercaseString]; 

    if ([key isEqualToString:@"name"]==YES) { 

     if (_eventName !=nil) { 
      [[MySingleton sharedInstance].userData setObject:_eventName forKey:@"eventName"]; 
     } 

     EventNameVC *nameEditor = [[EventNameVC alloc] initWithNibName:@"EventNameVC" bundle:nil]; 

     UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:nameEditor]; 
     [self presentViewController:nav animated:YES completion:nil]; 

     nav = nil; 
    } 

    if ([key isEqualToString:@"date"]==YES) { 

    } 

    if ([key isEqualToString:@"venue"]==YES) { 

    } 
} 

Этот код отображает мой UITableView и клетки правильно, я иду к мнению, внести изменения в текст и представить nsnotification.

-(IBAction) btnSave:(id)sender { 
    [self.txtName resignFirstResponder]; 

    NSDictionary *userInfo = [NSDictionary dictionaryWithObject:self.txtName.text forKey:@"eventName"]; 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"dismissModalView" object:self userInfo:userInfo]; 

    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

Все работает сейчас. Теперь uitableview обновляется без меня, чтобы прокручивать что-либо.

Это может быть какая-то глупая ошибка, но я счастлив, что теперь она решена.

Спасибо за помощь!

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