Обновление UITableView из UITableViewCell - PullRequest
7 голосов
/ 25 июня 2009

Есть ли простой способ вызвать [UITableView reloadData] из UITableViewCell? Я загружаю удаленные изображения, которые будут отображаться после первоначального отображения таблицы, и обновление изображения с помощью self.image = newImage не обновляет таблицу. Сброс текстового значения ячейки действительно обновляет таблицу, но это кажется небрежным.

MyTableViewCell.h

@interface MyTableViewCell : UITableViewCell {}
- (void)imageWasLoaded:(ImageData *) newImage;

MyTableViewCell.m

@implementation MyTableViewCell
- (void)imageWasLoaded:(UIImage *) newImageData {
    self.image = newImage; //does not refresh table

    //would like to call [self.tableView reloadData] here,
    //but self.tableView does not exist.

    //instead I use the below line
    self.text = self.text; //does refresh table
}
@end

Ответы [ 7 ]

18 голосов
/ 03 июля 2009

Я сделал именно то, что вы пытаетесь сделать. То, что вы ищете, это needsLayout. Для остроумия (это наблюдатель уведомления в моем подклассе UITableViewCell):

- (void)reloadImage:(NSNotification *)notification
{
    UIImage *image = [[SSImageManager sharedImageManager] getImage:[[notification userInfo] objectForKey:@"imageUrl"];
    [self setImage:image];
    [self setNeedsLayout];
}

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

5 голосов
/ 18 июля 2009

Получить ссылку на содержащий UITableView, используя свойство superview. Затем скажите это "reloadData":

UITableView *parentTable = (UITableView *)self.superview;
[parentTable reloadData];
0 голосов
/ 11 ноября 2014

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

Ответственность

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

Взломать для перезагрузки данных из ячейки

UITableView *parentTable = (UITableView *)self.superview;
if (![parentTable isKindOfClass:[UITableView class]]) {
    parentTable = (UITableView *) parentTable.superview;
}

[parentTable reloadData];
0 голосов
/ 28 июня 2013

CodeGrue прав. После нескольких дней размышлений о том, почему [subclassOjb.tableView reloadData] не работал, я бросил пытаться понять это и остановился на двух известных мне методах, которые работают, и их очень легко реализовать: 1- Центр уведомлений (из tableviewcell не следует использовать этот) 2- или используйте суперпредставление, чтобы получить указатель на свойство таблицы (это идеально подходит для uitableviewcells).

Обратите внимание, что использование метода superview будет работать только с вашим классом uitableviewcell. Скорее всего, если у вас есть пользовательская ячейка, у вас будет класс uitableviewcell, суперпредставлением которого является ваш tableviewcontroller или любой другой класс, который вы используете с делегатом uitableview + источником данных.

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

//handle tablview to show spinner (you have to lower your tableview out of the way yourself if you are calling this method)
[self.tableView setContentOffset:CGPointMake(0, -rf.frame.size.height) animated:YES];

//start spinner animation here
[rf beginRefreshing];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                         (unsigned long)NULL), ^(void) {
    // Load Data from data source class here
    [myDataSourceClass fetchDataMethod];

    dispatch_async(dispatch_get_main_queue(), ^{

         //Reload data and stop spinner
        [self.tableView reloadData];
        [rf endRefreshing];

        //handle tablview to hide spinner atrributed title
        [self.tableView setContentOffset:CGPointMake(0, 0) animated:YES];
    });
});

Если вы находитесь в другом представлении и что-то происходит, вам необходимо перезагрузить таблицу в представлении таблицы. В этот момент ваша таблица не отображается на экране, и нет причины, по которой вам следует перезагрузить таблицу, если ее никто не увидит. Просто добавьте [self.tableview reloadDAta] в ваш метод viewWillAppear, когда пользователи вернутся к вашему представлению tableviewcontroller, он перезагрузит таблицу на лету.

В любом случае для tableviewcell просто используйте следующее в вашем действии для перезагрузки Data (кредит CodeGrue)

UITableView *parentTable = (UITableView *)self.superview;
[parentTable reloadData];

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

self.tableView.delegate = self;
self.tableView.dataSource = self; 
0 голосов
/ 03 июля 2009

Хм. Итак, imageWasLoaded: - это метод делегата, вызываемый каким-то асинхронным кодом загрузки изображения? На самом деле кажется странным, что настройка self.image не обновляет изображение. Вы пытались добавить свой собственный UIImageView в ячейку вместо использования свойства изображения? Это может быть своего рода хаком, но таким образом изображение должно обновляться сразу (без необходимости перезагружать весь просмотр таблицы, что определенно нежелательно).

Еще лучше: если вы используете SDK 3.0, вы можете использовать новое свойство imageView в UITableViewCell (хотя я еще не пробовал):

self.imageView.image = newImage;

На самом деле, мне нужно было сделать то же самое несколько недель назад. Однако мой подход заключался в том, чтобы создать подкласс UIImageView и выполнить всю асинхронную загрузку / обновление изображений в этом классе. Основная причина, по которой я сделал это, заключалась в том, что я хотел иметь общий и многократно используемый компонент, который можно использовать в разных ячейках табличного представления (или в другом месте).

0 голосов
/ 26 июня 2009

Менее затратно перезагружать только те секции / строки, которые требуют перезагрузки. В iPhone SDK 3.0 есть несколько способов сделать это.

0 голосов
/ 25 июня 2009

try [yourtableview reloadData]; после установки изображения на новое изображение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...