Saya punya UITableView
dengan 5 UITableViewCells
. Setiap sel berisi UIButton
yang diatur sebagai berikut:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:1];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell viewWithTag:1];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
Pertanyaan saya adalah ini: dalam buttonPressedAction:
metode ini, bagaimana saya tahu tombol mana yang telah ditekan. Saya sudah mempertimbangkan menggunakan tag tetapi saya tidak yakin ini adalah rute terbaik. Saya ingin dapat memberi tag entah bagaimana indexPath
ke kontrol.
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
// how do I know which button sent this message?
// processing button press for this row requires an indexPath.
}
Apa cara standar untuk melakukan ini?
Edit:
Saya agak menyelesaikannya dengan melakukan hal berikut. Saya masih ingin memiliki pendapat apakah ini cara standar untuk melakukannya atau apakah ada cara yang lebih baik?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell.contentView.subviews objectAtIndex:0];
[button setTag:indexPath.row];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
int row = button.tag;
}
Yang penting untuk dicatat adalah bahwa saya tidak dapat menetapkan tag dalam pembuatan sel karena sel mungkin akan mati. Rasanya sangat kotor. Pasti ada cara yang lebih baik.
sumber
Jawaban:
Dalam sampel Aksesori Apple metode berikut digunakan:
Kemudian pada touch handler sentuh koordinat diambil dan jalur indeks dihitung dari koordinat itu:
sumber
Saya menemukan metode menggunakan superview superview untuk mendapatkan referensi ke indexPath sel bekerja dengan sempurna. Terima kasih kepada iphonedevbook.com (macnsmith) untuk teks tautan tip
sumber
Begini cara saya melakukannya. Sederhana dan ringkas:
sumber
CGPointZero
alih-alihCGPointMake(0, 0)
;-)Menemukan solusi yang bagus untuk masalah ini di tempat lain, tanpa bermain-main dengan tag pada tombol:
sumber
buttonPressedAction:
tapibuttonPressedAction:forEvent:
.Bagaimana dengan mengirim informasi seperti
NSIndexPath
padaUIButton
injeksi runtime using.1) Anda perlu runtime saat mengimpor
2) tambahkan konstanta statis
3) tambahkan
NSIndexPath
ke tombol Anda saat runtime menggunakan:(void) setMetaData: (id) target withObject: (id) newObj
4) pada tombol tekan dapatkan metadata menggunakan:
(id) metaData: (id) target
Nikmati
sumber
Untuk melakukan (@Vladimir) jawaban Swift:
Meskipun memeriksa
indexPath != nil
memberi saya jari ... "NSIndexPath bukan subtipe NSString"sumber
Dengan Swift 4.2 dan iOS 12, Anda dapat memilih satu dari 5 contoh lengkap berikut untuk menyelesaikan masalah Anda.
# 1. Menggunakan
UIView
'sconvert(_:to:)
danUITableView
' sindexPathForRow(at:)
# 2. Menggunakan
UIView
'sconvert(_:to:)
danUITableView
' sindexPathForRow(at:)
(alternatif)Ini merupakan alternatif dari contoh sebelumnya di mana kita meneruskan
nil
ketarget
parameter dalamaddTarget(_:action:for:)
. Dengan cara ini, jika responden pertama tidak melaksanakan tindakan, itu akan dikirim ke responden berikutnya dalam rantai responden sampai sampai implementasi yang tepat ditemukan.# 3. Menggunakan
UITableView
'sindexPath(for:)
dan pola delegasiDalam contoh ini, kami menetapkan pengontrol tampilan sebagai delegasi sel. Ketika tombol sel diketuk, itu memicu panggilan ke metode delegasi yang sesuai.
# 4 Menggunakan
UITableView
'sindexPath(for:)
dan penutupan untuk delegasiIni adalah alternatif dari contoh sebelumnya di mana kami menggunakan penutupan alih-alih deklarasi protokol-delegasi untuk menangani ketuk tombol.
# 5 Menggunakan
UITableViewCell
'saccessoryType
danUITableViewDelegate
' stableView(_:accessoryButtonTappedForRowWith:)
Jika tombol Anda adalah
UITableViewCell
's kontrol aksesori standar, setiap tap pada itu akan memicu panggilan untukUITableViewDelegate
' stableView(_:accessoryButtonTappedForRowWith:)
, memungkinkan Anda untuk mendapatkan indeks jalan terkait.sumber
sumber
Saya akan menggunakan properti tag seperti yang Anda katakan, mengatur tag seperti:
lalu masukkan tag ke dalam tombolTekanAction seperti:
Atau
sumber
tag
adalah bilangan bulat. tampaknya agak kikuk untuk encoding / decoding jalur indeks ke tag tampilan.Meskipun saya menyukai cara tag ... jika Anda tidak ingin menggunakan tag untuk alasan apa pun, Anda dapat membuat anggota
NSArray
tombol premade:kemudian buat tombol-tombol itu sebelum merender tableView dan dorong mereka ke dalam array.
Kemudian di dalam
tableView:cellForRowAtIndexPath:
fungsi yang dapat Anda lakukan:Kemudian dalam
buttonPressedAction:
fungsinya, Anda bisa melakukannyasumber
UNTUK MENANGANI BAGIAN - Saya menyimpan NSIndexPath di UITableViewCell khusus
DI CLKIndexPricesHEADERTableViewCell.xib
DALAM IB Tambahkan UIButton ke XIB - DONT tambahkan tindakan!
Tambahkan outlet @ properti (retain, nonatomik) IBOutlet UIButton * tombolIndexSectionClose;
JANGAN CTRL + MENGURANGI tindakan dalam IB (dilakukan dalam kode di bawah)
Dalam viewForHeaderInSection (juga harus bekerja untuk cellForRow .... dll jika tabel Anda hanya memiliki 1 bagian)
... gunakan bagian ini untuk mendapatkan data untuk sel Anda
... isi
USER menekan tombol DELETE pada header Section dan ini panggilan
Dalam contoh ini saya menambahkan tombol Hapus sehingga harus menunjukkan UIAlertView untuk mengonfirmasi
Saya menyimpan bagian dan memasukkan ke kamus menyimpan informasi tentang bagian dalam ivar di VC
sumber
sumber
Ini juga berfungsi untuk saya, Terima kasih @Cocoanut
Saya menemukan metode menggunakan superview superview untuk mendapatkan referensi ke indexPath sel bekerja dengan sempurna. Terima kasih kepada iphonedevbook.com (macnsmith) untuk teks tautan tip
sumber
Anda dapat menggunakan pola tag:
sumber
Apakah saya melewatkan sesuatu? Tidak bisakah Anda menggunakan pengirim untuk mengidentifikasi tombol. Pengirim akan memberi Anda info seperti ini:
Kemudian jika Anda ingin mengubah properti tombol, ucapkan gambar latar belakang yang baru saja Anda beri tahu pengirim:
Jika Anda membutuhkan tag maka metode ACBurk baik-baik saja.
sumber
Sebenarnya cukup mudah:
Bekerja dengan baik untuk saya: P
Jika Anda ingin menyesuaikan pengaturan aksi target, Anda dapat memasukkan parameter event dalam metode, dan kemudian menggunakan sentuhan event tersebut untuk menyelesaikan koordinat sentuhan. Koordinat masih perlu diselesaikan dalam batas tampilan sentuh, tetapi itu mungkin tampak lebih mudah bagi sebagian orang.
sumber
buat nsmutable array dan letakkan semua tombol di array itu ke [array addObject: yourButton];
dalam metode tekan tombol
-
sumber
Sedikit variasi pada jawaban Cocoanuts (yang membantu saya menyelesaikan masalah ini) ketika tombol berada di bagian bawah tabel (yang mencegah Anda menemukan 'sel yang diklik':
sumber
Saya selalu menggunakan tag.
Anda perlu subklas
UITableviewCell
dan menangani tombol tekan dari sana.sumber
Itu mudah; membuat sel khusus dan mengambil outlet tombol
ubah id dalam metode di atas menjadi
(UIButton *)
Anda bisa mendapatkan nilai tombol mana yang sedang diketuk dengan melakukan sender.tag.
sumber
Subkelas tombol untuk menyimpan nilai yang diperlukan, mungkin membuat protokol (ControlWithData atau sesuatu). Tetapkan nilai saat Anda menambahkan tombol ke sel tampilan tabel. Dalam acara touch up Anda, lihat apakah pengirim mematuhi protokol dan mengekstrak data. Saya biasanya menyimpan referensi ke objek aktual yang diberikan pada sel tampilan tabel.
sumber
UPDATE SWIFT 2
Inilah cara untuk mengetahui tombol mana yang disadap + mengirim data ke ViewController lain dari tombol itu
indexPath.row
karena saya berasumsi itulah intinya!Bagi mereka yang menggunakan kelas ViewController dan menambahkan tableView, saya menggunakan ViewController daripada TableViewController jadi saya secara manual menambahkan tableView untuk mengaksesnya.
Berikut adalah kode untuk meneruskan data ke VC lain ketika mengetuk tombol itu dan melewati sel
indexPath.row
sumber
Catatan di sini saya menggunakan sel khusus kode ini berfungsi dengan baik untuk saya
sumber
Solusi Chris Schwerdt tetapi kemudian di Swift bekerja untuk saya:
sumber
Masalah ini memiliki dua bagian:
1) Mendapatkan jalur indeks
UITableViewCell
yang berisi penekananUIButton
Ada beberapa saran seperti:
Memperbarui
UIButton
'stag
dicellForRowAtIndexPath:
metode menggunakan indeks jalan inirow
nilai. Ini bukan solusi yang baik karena membutuhkan pembaruantag
terus-menerus dan tidak bekerja dengan tampilan tabel dengan lebih dari satu bagian.Menambahkan
NSIndexPath
properti ke sel adat dan memperbarui itu bukannyaUIButton
'stag
dicellForRowAtIndexPath:
metode. Ini menyelesaikan beberapa bagian masalah tetapi masih tidak bagus karena selalu membutuhkan pembaruan.Menyimpan referensi yang lemah ke induk
UITableView
di sel khusus sambil membuat dan menggunakanindexPathForCell:
metode untuk mendapatkan jalur indeks. Tampaknya sedikit lebih baik, tidak perlu memperbarui apa pun dalamcellForRowAtIndexPath:
metode, tetapi masih memerlukan pengaturan referensi yang lemah ketika sel kustom dibuat.Menggunakan
superView
properti sel untuk mendapatkan referensi ke indukUITableView
. Tidak perlu menambahkan properti apa pun ke sel khusus, dan tidak perlu mengatur / memperbarui apa pun pada kreasi / nanti. Tetapi selsuperView
tergantung pada detail implementasi iOS. Jadi tidak bisa digunakan secara langsung.Tetapi ini dapat dicapai dengan menggunakan loop sederhana, karena kami yakin sel yang dimaksud harus dalam UITableView:
Jadi, saran ini dapat digabungkan menjadi metode sel kustom yang sederhana dan aman untuk mendapatkan jalur indeks:
Mulai sekarang, metode ini dapat digunakan untuk mendeteksi yang
UIButton
ditekan.2) Memberitahu pihak lain tentang acara tekan tombol
Setelah secara internal mengetahui yang
UIButton
ditekan di mana sel khusus dengan jalur indeks yang tepat, informasi ini perlu dikirim ke pihak lain (kemungkinan besar pengendali tampilan menanganiUITableView
). Jadi, acara klik tombol ini dapat ditangani dalam tingkat abstraksi dan logika yang serupa dengandidSelectRowAtIndexPath:
metode delegasi UITableView.Dua pendekatan dapat digunakan untuk ini:
a) Delegasi: sel khusus dapat memiliki
delegate
properti dan dapat mendefinisikan protokol. Ketika tombol ditekan itu hanya menjalankan metode pendelegasian padadelegate
properti itu. Tetapidelegate
properti ini perlu disetel untuk setiap sel khusus ketika dibuat. Sebagai alternatif, sel kustom dapat memilih untuk melakukan metode delegasinya pada tampilan tabel induknyadelegate
juga.b) Pusat Pemberitahuan: sel khusus dapat menentukan nama pemberitahuan kustom dan memposting pemberitahuan ini dengan jalur indeks dan informasi tampilan tabel induk yang disediakan dalam
userInfo
objek. Tidak perlu mengatur apa pun untuk setiap sel, cukup menambahkan pengamat untuk notifikasi sel kustom sudah cukup.sumber
Saya menggunakan solusi yang subclass
UIButton
dan saya pikir saya harus membagikannya di sini, kode di Swift:Maka ingatlah untuk memperbarui indexPath di
cellForRow(at:)
Jadi ketika merespons acara tombol Anda dapat menggunakannya seperti
sumber