2010-09-19 2 views
53

У меня есть верхний уровень UIViewController, который содержит UITableView. Верхний уровень UIViewController создает экземпляр NavigationController и нажимает UIViewController на NavigationController. И.Е. мы выдвигаем новый, второй взгляд. Это второе представление имеет обычную кнопку «Назад» в верхнем левом углу, чтобы вы могли вернуться к виду верхнего уровня.Перезагрузка UITableView при навигации назад?

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

ответ

105

Все, что вам нужно сделать, это это (в вашем UIViewController с UITableView). На данный момент вам не нужно беспокоиться о том, что происходит на клеточном уровне.

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    [self.tableView reloadData]; // to reload selected cell 
} 

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

+1

я использовал этот метод, но должен был переместить код из моего didViewLoad в viewWillAppear, как они, где и стрельбы на начальной загрузке. Для меня это была большая проблема, потому что мне нужно загрузить новые данные о деталях из веб-службы. – PowerMan2015

5

Вы можете реализовать методы UINavigationControllerDelegate и создать логику для обновления при появлении контроллеров.

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

Если вам нужно отправить данные с второго контроллера представления на первый контроллер представления, помните, что ваш второй контроллер просмотра «не знает» о существовании предыдущего контроллера представлений. Он должен быть прозрачным для него. Вы должны реализовать некоторый протокол, чтобы второй контроллер представления данных передал данные на первый контроллер представления. Это будет третий вариант этой проблемы, так как ваш первый контроллер представления будет делегатом, а второй контроллер представления отправит информацию делегату, вы можете подготовить свой табличный вид (контроллер первого представления) для перезагрузки на основе полученные данные.

10

Если вы хотите, чтобы перезагрузить ячейку, которая была выбрана, переопределения viewWillAppear: в пользовательском подклассе UITableViewController так:

- (void)viewWillAppear:(BOOL)animated 
{ 
    NSIndexPath *selectedRowIndexPath = [self.tableView indexPathForSelectedRow]; 
    [super viewWillAppear:animated]; // clears selection 
    if (selectedRowIndexPath) { 
     [self.tableView reloadRowsAtIndexPaths:@[selectedRowIndexPath] withRowAnimation:UITableViewRowAnimationNone]; 
    } 
} 

Примечание: Предположим, что вы оставили clearsSelectionOnViewWillAppear набор для YES (по умолчанию), вы должны получить индексный путь для выбранной строки перед вызовом super, который очищает выбор.

Кроме того, solution of @ZoranSimic, чтобы просто позвонить [self.tablView reloadData], является приемлемым, так как он меньше кода и по-прежнему эффективен.

Наконец, возможно, лучший способ сохранить клетки вашего представления в виде таблицы в синхронизации с объектами модели, которые они представляют, чтобы сделать как NSFetchedResultsController и использовать ключ-значение наблюдений (КВО) и/или NSNotification информировать контроллер представления в виде таблицы модели объекты изменились, чтобы они могли перезагрузить соответствующие ячейки. Контроллер табличного вида может начать наблюдать изменения своих объектов модели в viewDidLoad и заканчивать наблюдение в dealloc (и где угодно вы manually unload self.view).

6

В дополнение к answer of Zoran Simic здесь Свифт код:

override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(animated) 
    tableView.reloadData() 
} 
+0

Будьте осторожны, чтобы не получать данные из 'viewDidLoad()', если вы хотите перезагрузить данные из 'viewWillAppear()'. –

1

Возможно может помочь в настоящее время.

Для Swift 2+

В вашем методе viewDidAppear:

Если вы хотите, чтобы перезагрузить всю таблицу:

tableView.reloadData() 

Если вы хотите, чтобы перезагрузить выбран только клетка.

let index = tableView.indexPathForSelectedRow 
if (index != nil){ 
    self.tableView.reloadRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Automatic) 
} 
2

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

создать одну переменную в .h file из моих ViewController для проверки того, что это первый раз, когда я иду к этому ViewController или когда я вернуться обратно

@property (nonatomic) BOOL isViewExist; 

После этого в viewWillAppear

-(void)viewWillAppear:(BOOL)animated{ 
    if(!self.isViewExist){ 
     self.isViewExist = YES; // check it is the first time you go to this ViewController -> don't reload anything 
    }else{ 
     [self.tableView reloadData]; // to reload the tableview data 
     // or your can refresh anything in your ViewController as you want 
    } 
} 

Надеется, что это помощь

-1

Обновления для Swift 3

let index = tableView.indexPathForSelectedRow 
    if (index != nil){ 
     self.tableView.reloadRows(at: [index!], with: UITableViewRowAnimation.automatic) 
    } 
+0

_in - override func viewDidLoad() или ??? _ - комментирование от имени пользователя, который не может комментировать – Tushar