UITableView'da tek bir UITableViewCell'i yenilemek mümkün mü?


182

S UITableViewkullanarak özel bir var UITableViewCell. Her UITableViewCellbirinin 2 düğmesi vardır. Bu düğmelere tıklamak UIImageViewhücrenin içindeki bir görüntüyü değiştirir .

Yeni görüntüyü görüntülemek için her bir hücreyi ayrı ayrı yenilemek mümkün mü? Herhangi bir yardım takdir.

Yanıtlar:


323

Hücrenizin indexPath değerine sahip olduğunuzda, aşağıdakine benzer bir şey yapabilirsiniz:

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

Xcode 4.6 ve üstü sürümlerde:

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

Tabii ki, animasyon efekti olarak istediğinizi ayarlayabilirsiniz.


4
Burada nitpicking, ancak elbette sadece tek bir hücreyi yeniliyor olsaydınız, muhtemelen kullanmak istersiniz [NSArray arrayWithObject:].
Leo Cassarani

57
Ayrıca, bu durumda, beginUpdatesve endUpdatesgereksizdir.
kubi

2
OP yüzden / endupdates başlayacak aramaya gerek yok, bir şey animasyon değil
kubi

2
Yöntem , son herkese açık Xcode sürümünde kullanımdan kaldırılmadığını söylemediği sürece , tüm iOS sürümleri iyi olmalıdır.
Alejandro Iván

1
@Supertecnoboff true, ancak bir noktada değiştirilebilir veya davranışını değiştirir. En kısa sürede amortismanları ele almak daha iyi
Alejandro Iván

34

Sadece aramayı denedim -[UITableView cellForRowAtIndexPath:], ama işe yaramadı. Ancak, örneğin benim için aşağıdakiler işe yarar. Ben allocve sıkı bellek yönetimi.releaseNSArray

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

Burada [indexPaths sürümü] gerekli mi? Sadece nesneyi kendiniz tahsis ederseniz buna ihtiyacınız olduğunu düşündüm.
powerj1984

4
İndexPaths dizisini ayırdı. Ama daha iyi soru, neden "sıkı bellek yönetimi" gerektiğini düşündüğü. Otomatik çalıştırma işi burada mükemmel bir şekilde yapacak.
John Cromartie

22

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()
}

Bu yöntemi nereye çağırmalı?
Master AgentX

18

reloadRowsAtIndexPaths:iyi, ama yine de UITableViewDelegateyöntemleri ateş etmeye zorlayacak .

Hayal edebileceğim en basit yaklaşım:

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

Bu var önemli sizin çağırmak için configureCell:, ana iş parçacığı üzerinde uygulanmasını olmayan UI iş parçacığı üzerinde alışkanlık çalışması (aynı hikaye reloadData/ ' reloadRowsAtIndexPaths:). Bazen eklemek yararlı olabilir:

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

Ayrıca, şu anda görünür olan görünümün dışında yapılacak işlerden kaçınmaya değer:

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

Neden temsilci çağrılmasını istemiyorsunuz?
kernix

ReloadRowsAtIndexPaths: veya reloadData yöntemlerinin aksine tablo görünümünü en üste kaydırmaya zorlamadığından bu en iyi yaklaşımdır.
ZviBar

Bunu yaptım ve hücrenin geri dönüştürüldüğü gerçeğiyle yakalandım
Travelling Man

16

Özel TableViewCells kullanıyorsanız, genel

[self.tableView reloadData];    

mevcut görünümden ayrılmadıkça bu soruya etkili bir şekilde cevap vermez çıkıp geri . İlk cevap da vermiyor.

İlk tablo görünümü hücrenizi görünümler arasında geçiş yapmadan başarıyla yeniden yüklemek için aşağıdaki kodu kullanın:

//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];
}

Yalnızca üst hücreyi (veya isterseniz tüm tablo görünümünü) özel olarak yeniden yükleyebilmeniz için yukarıdaki yöntemi çağıran aşağıdaki yenileme yöntemini ekleyin :

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

    //finish refreshing 
    [refreshControl endRefreshing];
}

Artık bu sıralamaya sahip olduğunuza göre, viewDidLoadaşağıdakileri ekleyin:

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

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

[self.tableView addSubview:refreshControl];

Artık üst hücreyi yeniden yükleyecek özel bir yenileme tablosu özelliğiniz var. Tüm tabloyu yeniden yüklemek için

[self.tableView reloadData]; yeni yenileme yönteminize.

Görünümleri her değiştirdiğinizde verileri yeniden yüklemek istiyorsanız, yöntemi uygulayın:

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

6

Hızlı 3:

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

4

Bu yanıtları iOS 6'daki yeni değişmez sözdizimiyle biraz güncellemek için - tek bir nesne için Paths = @ [indexPath] veya birden çok nesne için Paths = @ [indexPath1, indexPath2, ...] kullanabilirsiniz.

Şahsen, dizilerin ve sözlüklerin son derece sözdiziminin son derece yararlı ve büyük zaman kazandırıcı olduğunu buldum. Bir kere okumak daha kolay. Ve her zaman kişisel bir bugaboo olan herhangi bir çok nesne listesinin sonunda bir nil ihtiyacını ortadan kaldırır. Eğilecek yel değirmenlerimiz var, değil mi? ;-)

Sadece bunu karýţýma atacađýmý düţündüm. Umarım yardımcı olur.


Greg de, aslında o sözdiziminin bir örneği nedir, lütfen? Teşekkürler!
Fattie

3

Swift 5 ile birlikte bir UITableView uzantısı:

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()
    }

}

İle ara

self.tableView.updateRow(row: 1)

0

Yükseltme hücresine ihtiyacım var ama klavyeyi kapatmak istiyorum. Kullanırsam

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

klavye kayboluyor

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.