Можно ли обновить один UITableViewCell в UITableView? - PullRequest
175 голосов
/ 15 декабря 2010

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

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

Ответы [ 8 ]

317 голосов
/ 15 декабря 2010

Когда у вас есть 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]; 

Вы можете установить все, что захотите, в качестве анимацииэффект, конечно.

34 голосов
/ 06 мая 2011

Я пытался просто позвонить -[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];
}
20 голосов
/ 20 ноября 2014

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()
}
18 голосов
/ 20 января 2015

reloadRowsAtIndexPaths: хорошо, но все равно заставит запускать UITableViewDelegate методы.

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

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

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

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

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

BOOL cellIsVisible = [[self.tableView indexPathsForVisibleRows] indexOfObject:indexPath] != NSNotFound;
if (cellIsVisible)
{
    ....
}
16 голосов
/ 13 октября 2014

Если вы используете пользовательские 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 голосов
/ 23 января 2017

Свифт 3:

tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
4 голосов
/ 21 января 2013

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

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

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

0 голосов
/ 04 августа 2017

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

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

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

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