Apakah mungkin untuk me-refresh satu UITableViewCell dalam UITableView?


182

Saya punya kebiasaan UITableViewmenggunakan UITableViewCells. Masing-masing UITableViewCellmemiliki 2 tombol. Mengklik tombol-tombol ini akan mengubah gambar di UIImageViewdalam sel.

Apakah mungkin untuk menyegarkan setiap sel secara terpisah untuk menampilkan gambar baru? Bantuan apa pun dihargai.

Jawaban:


323

Setelah Anda memiliki indexPath sel Anda, Anda dapat melakukan sesuatu seperti:

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

Dalam Xcode 4.6 dan lebih tinggi:

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

Anda dapat mengatur apa pun yang Anda suka sebagai efek animasi, tentu saja.


4
Nitpicking di sini, tetapi tentu saja jika Anda hanya menyegarkan satu sel, Anda mungkin ingin menggunakannya [NSArray arrayWithObject:].
Leo Cassarani

57
Juga, dalam situasi ini, beginUpdatesdan endUpdatestidak perlu.
kubi

2
OP tidak menjiwai apa pun, jadi tidak perlu memanggil awal / akhir
kubi

2
Selama metode ini tidak mengatakan usang dalam versi Xcode publik terakhir, semua versi iOS harus baik-baik saja.
Alejandro Iván

1
@Supertecnoboff benar, tetapi pada titik tertentu dapat diganti atau akan mengubah perilakunya. Lebih baik menangani penghentian sesegera mungkin
Alejandro Iván

34

Saya mencoba menelepon -[UITableView cellForRowAtIndexPath:], tetapi itu tidak berhasil. Tapi, berikut ini berfungsi untuk saya misalnya. Aku allocdan releaseyang NSArrayuntuk manajemen memori yang ketat.

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

Apakah [rilis indexPaths] perlu di sini? Saya pikir Anda hanya perlu itu jika Anda mengalokasikan objek sendiri.
powerj1984

4
Dia memang mengalokasikan array indexPaths. Tetapi pertanyaan yang lebih baik adalah mengapa ia berpikir "manajemen memori ketat" diperlukan. Autorelease akan melakukan pekerjaan dengan sangat baik di sini.
John Cromartie

22

Cepat:

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

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

Di mana harus memanggil metode ini?
Master AgentX

18

reloadRowsAtIndexPaths:baik-baik saja, tetapi masih akan memaksa UITableViewDelegatemetode untuk menembak.

Pendekatan paling sederhana yang dapat saya bayangkan adalah:

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

Ini penting untuk memohon Anda configureCell:pelaksanaan pada thread utama, karena itu tidak akan berhasil di thread non-UI (cerita yang sama dengan reloadData/ reloadRowsAtIndexPaths:). Terkadang mungkin bermanfaat untuk menambahkan:

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

Layak juga untuk menghindari pekerjaan yang akan dilakukan di luar tampilan yang saat ini terlihat:

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

Mengapa Anda tidak ingin delegasi dipanggil?
kernix

Ini adalah pendekatan terbaik karena tidak memaksa tampilan tabel untuk menggulir semua jalan ke atas yang bertentangan dengan reloadRowsAtIndexPaths: atau metode reloadData.
ZviBar

Saya melakukan ini dan akhirnya tertangkap oleh fakta bahwa sel itu didaur ulang
Travelling Man

16

Jika Anda menggunakan TableViewCells khusus, generik

[self.tableView reloadData];    

tidak secara efektif menjawab pertanyaan ini kecuali Anda meninggalkan tampilan saat ini dan kembali. Tidak juga jawaban pertama.

Untuk berhasil memuat ulang sel tampilan tabel pertama Anda tanpa beralih tampilan , gunakan kode berikut:

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

Masukkan metode penyegaran berikut yang memanggil metode di atas sehingga Anda dapat memuat ulang hanya sel atas (atau seluruh tampilan tabel jika diinginkan):

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

    //finish refreshing 
    [refreshControl endRefreshing];
}

Sekarang Anda memiliki yang diurutkan, di dalam Anda viewDidLoadtambahkan yang berikut:

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

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

[self.tableView addSubview:refreshControl];

Anda sekarang memiliki fitur tabel penyegaran khusus yang akan memuat ulang sel atas. Untuk memuat ulang seluruh tabel, tambahkan

[self.tableView reloadData]; ke metode penyegaran baru Anda.

Jika Anda ingin memuat ulang data setiap kali Anda beralih tampilan, terapkan metode ini:

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

4

Hanya untuk memperbarui jawaban ini sedikit dengan sintaks literal baru di iOS 6 - Anda dapat menggunakan Paths = @ [indexPath] untuk objek tunggal, atau Paths = @ [indexPath1, indexPath2, ...] untuk beberapa objek.

Secara pribadi, saya telah menemukan sintaks literal untuk array dan kamus sangat bermanfaat dan menghemat waktu. Hanya saja lebih mudah dibaca, untuk satu hal. Dan itu menghilangkan kebutuhan untuk nol di akhir daftar multi-objek, yang selalu menjadi bugaboo pribadi. Kita semua punya kincir angin untuk dimiringkan, ya? ;-)

Hanya berpikir saya akan membuang ini ke dalam campuran. Semoga ini bisa membantu.


Katakanlah Greg, apa sebenarnya contoh dari sintaks itu di sana? Terima kasih!
Fattie

3

Berikut ini adalah ekstensi UITableView dengan 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()
    }

}

Telepon dengan

self.tableView.updateRow(row: 1)

0

Saya perlu sel upgrade tetapi saya ingin menutup keyboard. Jika saya gunakan

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

keyboard menghilang

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.