Возможно ли обновить один UITableViewCell в UITableView?

У меня есть пользовательский UITableView с помощью UITableViewCell s. Каждый UITableViewCell имеет 2 кнопки. Нажатие этих кнопок изменит изображение в UIImageView внутри ячейки.

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

Ответ 1

Как только у вас есть indexPath вашей ячейки, вы можете сделать что-то вроде:

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPathOfYourCell, nil] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; 

В Xcode 4.6 и выше:

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; 

Конечно, вы можете настроить все, что угодно, как эффект анимации.

Ответ 2

Я попробовал просто позвонить -[UITableView cellForRowAtIndexPath:], но это не сработало. Но, например, для меня работает следующее. я alloc и release NSArray для жесткого управления памятью.

- (void)reloadRow0Section0 {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    NSArray *indexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];
    [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
    [indexPaths release];
}

Ответ 3

Swift:

func updateCell(path:Int){
    let indexPath = NSIndexPath(forRow: path, inSection: 1)

    tableView.beginUpdates()
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) //try other animations
    tableView.endUpdates()
}

Ответ 4

reloadRowsAtIndexPaths: отлично, но все равно будет принудительно срабатывать методы UITableViewDelegate.

Самый простой способ, который я могу себе представить, это:

UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self configureCell:cell forIndexPath:indexPath];

Он важный, чтобы вызвать вашу реализацию configureCell: в основном потоке, так как он не будет работать с потоком, отличным от UI (та же история с reloadData/reloadRowsAtIndexPaths:). Иногда бывает полезно добавить:

dispatch_async(dispatch_get_main_queue(), ^
{
    [self configureCell:cell forIndexPath:indexPath];
});

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

BOOL cellIsVisible = [[self.tableView indexPathsForVisibleRows] indexOfObject:indexPath] != NSNotFound;
if (cellIsVisible)
{
    ....
}

Ответ 5

Если вы используете пользовательские TableViewCells, общий

[self.tableView reloadData];    

не отвечает на этот вопрос , если вы не оставите текущий вид и не вернетесь. И первый ответ тоже.

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

//For iOS 5 and later
- (void)reloadTopCell {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    NSArray *indexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];
    [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}

Вставьте следующий метод обновления, который вызывает описанный выше метод, чтобы вы могли настраивать только верхнюю ячейку (или весь вид таблицы, если хотите):

- (void)refresh:(UIRefreshControl *)refreshControl {
    //call to the method which will perform the function
    [self reloadTopCell];

    //finish refreshing 
    [refreshControl endRefreshing];
}

Теперь, когда у вас есть это, внутри viewDidLoad добавьте следующее:

//refresh table view
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];

[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];

[self.tableView addSubview:refreshControl];

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

[self.tableView reloadData]; к вашему новому методу обновления.

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

//ensure that it reloads the table view data when switching to this view
- (void) viewWillAppear:(BOOL)animated {
    [self.tableView reloadData];
}

Ответ 6

Swift 3:

tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()

Ответ 7

Просто, чтобы немного обновить эти ответы с новым синтаксисом literal в iOS 6, вы можете использовать Paths = @[indexPath] для одного объекта или Paths = @[indexPath1, indexPath2,...] для нескольких объектов.

Лично я нашел буквальный синтаксис для массивов и словарей, которые были бы очень полезны и величайшие таймеры. Во-первых, это просто читать. И это устраняет необходимость в нуле в конце любого списка нескольких объектов, который всегда был личным bugaboo. У всех нас есть свои ветряные мельницы, чтобы наклониться, да?; -)

Просто подумал, что я брошу это в микс. Надеюсь, что это поможет.

Ответ 8

Мне нужна ячейка обновления, но я хочу закрыть клавиатуру. Если я использую

let indexPath = NSIndexPath(forRow: path, inSection: 1)
tableView.beginUpdates()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) //try other animations
tableView.endUpdates()

клавиатура исчезает

Ответ 9

Вот расширение UITableView с Swift 5:

import UIKit

extension UITableView
{    
    func updateRow(row: Int, section: Int = 0)
    {
        let indexPath = IndexPath(row: row, section: section)

        self.beginUpdates()
        self.reloadRows(at: [indexPath as IndexPath], with: UITableView.RowAnimation.automatic)
        self.endUpdates()
    }

}

Позвонить с помощью

self.tableView.updateRow(row: 1)