Pertanyaannya sederhana: Bagaimana Anda memuat custom UITableViewCell
dari file Xib? Melakukannya memungkinkan Anda menggunakan Interface Builder untuk mendesain sel Anda. Jawabannya ternyata tidak sederhana karena masalah manajemen memori. Utas ini menyebutkan masalah dan menyarankan solusi, tetapi merupakan pra-rilis NDA dan tidak memiliki kode. Inilah utas panjang yang membahas masalah ini tanpa memberikan jawaban yang pasti.
Berikut beberapa kode yang saya gunakan:
static NSString *CellIdentifier = @"MyCellIdentifier";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (MyCell *)[nib objectAtIndex:0];
}
Untuk menggunakan kode ini, buat MyCell.m / .h, subclass baru UITableViewCell
dan tambahkan IBOutlets
untuk komponen yang Anda inginkan. Kemudian buat file "Empty XIB" baru. Buka file Xib di IB, tambahkan UITableViewCell
objek, atur pengenalnya ke "MyCellIdentifier", dan atur kelasnya ke MyCell dan tambahkan komponen Anda. Akhirnya, hubungkan IBOutlets
ke komponen. Perhatikan bahwa kami tidak menetapkan Pemilik File di IB.
Metode lain menganjurkan pengaturan Pemilik File dan memperingatkan kebocoran memori jika Xib tidak dimuat melalui kelas pabrik tambahan. Saya menguji di atas di bawah Instrumen / Kebocoran dan tidak melihat kebocoran memori.
Jadi apa cara kanonik untuk memuat sel dari Xibs? Apakah kita menetapkan Pemilik File? Apakah kita memerlukan pabrik? Jika demikian, seperti apa kode untuk pabrik itu? Jika ada beberapa solusi, mari kita perjelas pro dan kontra dari masing-masing ...
sumber
Jawaban:
Berikut adalah dua metode yang menyatakan penulis asli direkomendasikan oleh seorang insinyur IB .
Lihat posting aktual untuk lebih jelasnya. Saya lebih suka metode # 2 karena tampaknya lebih sederhana.
Metode # 1:
Metode # 2:
Pembaruan (2014): Metode # 2 masih valid tetapi tidak ada dokumentasi untuk itu lagi. Dulu berada di dokumen resmi tetapi sekarang dihapus demi storyboard.
Saya memposting contoh yang berfungsi di Github:
https://github.com/bentford/NibTableCellExample
edit untuk Swift 4.2
sumber
Solusi yang tepat adalah ini:
sumber
Daftar
Setelah iOS 7, proses ini disederhanakan menjadi ( swift 3.0 ):
Dequeue
Dan nanti, dequeued using ( swift 3.0 ):
Perbedaannya adalah bahwa metode baru ini tidak hanya menghilangkan sel, tetapi juga membuat jika tidak ada (itu berarti Anda tidak perlu melakukan
if (cell == nil)
shenanigans), dan sel siap digunakan seperti pada contoh di atas.Dan tentu saja, tipe kelas sel yang terkait adalah yang Anda definisikan dalam file .xib untuk
UITableViewCell
subkelas, atau sebagai alternatif, menggunakan metode register lainnya.Konfigurasi
Idealnya, sel Anda telah dikonfigurasikan dalam hal tampilan dan pemosisian konten (seperti label dan tampilan gambar) pada saat Anda mendaftarkannya, dan pada
cellForRowAtIndexPath
metode Anda cukup mengisinya.Bersama
Dan tentu saja, ini semua tersedia di ObjC dengan nama yang sama.
sumber
[self.tableView registerNib:[UINib nibWithNibName:@"BlaBlaTableViewCell" bundle:nil] forCellReuseIdentifier:kCellIdentifier];
Mengambil jawaban Shawn Craver dan membersihkannya sedikit.
BBCell.h:
BBCell.m:
Saya membuat semua subclass UITableViewCell saya dari BBCell, dan kemudian mengganti standar
dengan:
sumber
Saya menggunakan Metode bentford's # 2 :
Ini berfungsi, tetapi perhatikan koneksi ke Pemilik File di file .xib UITableViewCell kustom Anda.
Dengan melewati
owner:self
di AndaloadNibNamed
pernyataan, Anda menetapkanUITableViewController
sebagai Berkas ini Pemilik AndaUITableViewCell
.Jika Anda menyeret dan melepaskan ke file header di IB untuk mengatur tindakan dan outlet, itu akan mengaturnya sebagai Pemilik File secara default.
Di
loadNibNamed:owner:options
, kode Apple akan mencoba mengatur properti pada AndaUITableViewController
, karena itulah pemiliknya. Tapi Anda tidak memiliki properti-properti yang didefinisikan di sana, sehingga Anda mendapatkan kesalahan tentang menjadi kode-compliant nilai kunci :Jika suatu Acara dipicu sebagai gantinya, Anda akan mendapatkan NSInvalidArgumentException:
Solusi yang mudah adalah mengarahkan koneksi Builder Interface Anda di
UITableViewCell
bukan Pemilik File:sumber
Saya telah memutuskan untuk mengirim karena saya tidak suka jawaban ini - semuanya selalu bisa lebih sederhana dan sejauh ini adalah cara paling ringkas yang saya temukan.
1. Bangun Xib Anda di Interface Builder sesuka Anda
2. Di subkelas UIViewController atau UITableViewController Anda
3. Di MyTableViewCellSubclass Anda
sumber
Jika Anda menggunakan Interface Builder untuk membuat sel, periksa apakah Anda telah menetapkan Pengidentifikasi di Inspektur. Kemudian periksa apakah itu sama ketika memanggil dequeueReusableCellWithIdentifier.
Saya tidak sengaja lupa untuk menetapkan beberapa pengidentifikasi dalam proyek yang berat, dan perubahan kinerja seperti siang dan malam.
sumber
Memuat UITableViewCells dari XIB menghemat banyak kode, tetapi biasanya menghasilkan kecepatan pengguliran yang mengerikan (sebenarnya, bukan XIB tetapi penggunaan berlebihan UIViews yang menyebabkan ini).
Saya sarankan Anda melihat ini: Referensi tautan
sumber
Inilah metode kelas yang telah saya gunakan untuk membuat sel khusus dari XIB:
Kemudian, di XIB, saya menetapkan nama kelas, dan menggunakan kembali pengidentifikasi. Setelah itu, saya bisa memanggil metode itu di pengontrol tampilan saya bukan
Ini cukup cepat, dan digunakan dalam dua aplikasi pengiriman saya. Ini lebih dapat diandalkan daripada menelepon
[nib objectAtIndex:0]
, dan dalam pikiran saya setidaknya, lebih dapat diandalkan daripada contoh Stephan Burlot karena Anda dijamin hanya mengambil pandangan dari XIB yang merupakan tipe yang tepat.sumber
Solusi yang benar adalah ini
sumber
Muat ulang NIB itu mahal. Lebih baik memuatnya sekali, lalu instantiate objek saat Anda membutuhkan sel. Perhatikan bahwa Anda dapat menambahkan UIImageViews dll ke nib, bahkan beberapa sel, menggunakan metode ini (Apple "registerNIB" iOS5 hanya memungkinkan satu objek tingkat atas - Bug 10580062 "Tabel iOS5 lihat registerNib: terlalu ketat"
Jadi kode saya di bawah ini - Anda membaca di NIB sekali (inisialisasi seperti yang saya lakukan atau di viewDidload - apa pun. Sejak saat itu, Anda instantiate nib ke objek kemudian pilih yang Anda butuhkan. Ini jauh lebih efisien daripada memuat nib lagi dan lagi.
sumber
Lihat ini - http://eppz.eu/blog/custom-uitableview-cell/ - cara yang sangat nyaman menggunakan kelas kecil yang berakhir satu baris dalam implementasi controller:
sumber
Cara yang benar untuk melakukannya adalah dengan membuat implementasi subclass, header, dan XIB UITableViewCell. Di XIB hapus tampilan apa pun dan cukup tambahkan sel tabel. Atur kelas sebagai nama subclass UITableViewCell. Untuk pemilik file, buatlah nama kelas subclass UITableViewController. Hubungkan pemilik file ke sel menggunakan outlet tableViewCell.
Dalam file header:
Dalam file implementasi:
sumber
Apa yang saya lakukan untuk ini adalah mendeklarasikan
IBOutlet UITableViewCell *cell
di kelas controller Anda. Kemudian aktifkanNSBundle loadNibNamed
metode kelas, yang akan memberi makanUITableViewCell
ke sel yang dinyatakan di atas.Untuk xib, saya akan membuat xib kosong dan menambahkan
UITableViewCell
objek di IB di mana ia dapat diatur sesuai kebutuhan. Pandangan ini kemudian dihubungkan ke selIBOutlet
di kelas controller.Tambahan NSBundle loadNibNamed (ADC login)
Artikel cocoawithlove.com Saya bersumber dari konsep (dapatkan aplikasi sampel nomor telepon)
sumber
Buat
AbcViewCell
subclass kelas Anda sendiri yang disesuaikan dariUITableViewCell
(Pastikan nama file kelas dan nama file nib Anda sama)Buat metode kelas ekstensi ini.
Gunakan.
let cell: AbcViewCell = UITableViewCell.fromNib()
sumber
Pertama impor file sel kustom Anda
#import "CustomCell.h"
dan kemudian ubah metode delegasi seperti yang disebutkan di bawah ini:sumber
Di Swift 4.2 dan Xcode 10
Saya memiliki tiga file sel XIB
di ViewDidLoad daftarkan file XIB Anda seperti ini ...
Ini adalah pendekatan pertama
Pendekatan kedua secara langsung mendaftarkan file XIB di cellForRowAt indexPath:
Ini adalah fungsi delegasi tampilan tabel saya
sumber
Berikut adalah metode saya untuk itu: Memuat UITableViewCells Kustom dari File XIB ... Namun Metode Lain
Idenya adalah untuk membuat subkelas SampleCell dari
UITableViewCell
denganIBOutlet UIView *content
properti dan properti untuk setiap subview kustom yang perlu Anda konfigurasi dari kode. Kemudian untuk membuat file SampleCell.xib. Di file nib ini, ubah pemilik file ke SampleCell. Tambahkan kontenUIView
berukuran sesuai dengan kebutuhan Anda. Tambahkan dan konfigurasikan semua subview (label, tampilan gambar, tombol, dll) yang Anda inginkan. Terakhir, tautkan tampilan konten dan subview ke pemilik file.sumber
Berikut ini adalah pendekatan universal untuk mendaftarkan sel di
UITableView
:Penjelasan:
Reusable
protokol menghasilkan ID sel dari nama kelasnya. Pastikan Anda mengikuti konvensi tersebut:cell ID == class name == nib name
.UITableViewCell
sesuai denganReusable
protokol.UITableView
ekstensi abstrak menghilangkan perbedaan dalam mendaftarkan sel melalui nib atau kelas.Contoh penggunaan:
sumber
Saya tidak tahu apakah ada cara kanonik, tapi inilah metode saya:
Dan gunakan kode ini:
Dalam contoh Anda, menggunakan
dapat rusak jika Apple mengubah urutan item dalam xib.
sumber
sumber
Ekstensi ini membutuhkan Xcode7 beta6
Buat file Xib yang hanya berisi 1 UITableViewCell kustom.
Muat
sumber
sumber