Saya memiliki tampilan tabel dengan tombol dan saya ingin menggunakan indexpath.row ketika salah satunya diketuk. Ini yang saat ini saya miliki, tetapi selalu 0
var point = Int()
func buttonPressed(sender: AnyObject) {
let pointInTable: CGPoint = sender.convertPoint(sender.bounds.origin, toView: self.tableView)
let cellIndexPath = self.tableView.indexPathForRowAtPoint(pointInTable)
println(cellIndexPath)
point = cellIndexPath!.row
println(point)
}
swift
button
touch
nsindexpath
Vincent
sumber
sumber
Jawaban:
giorashc hampir mendapatkannya dengan jawabannya, tetapi dia mengabaikan fakta bahwa sel memiliki
contentView
lapisan ekstra . Jadi, kita harus melangkah lebih dalam:Ini karena dalam hierarki tampilan, tableView memiliki sel sebagai subview yang kemudian memiliki 'tampilan konten' sendiri, inilah mengapa Anda harus mendapatkan tampilan super tampilan konten ini untuk mendapatkan sel itu sendiri. Akibatnya, jika tombol Anda berada dalam subview dan bukan langsung ke tampilan konten sel, Anda harus masuk lebih dalam beberapa lapisan untuk mengaksesnya.
Di atas adalah salah satu pendekatan seperti itu, tetapi belum tentu merupakan pendekatan terbaik. Meskipun berfungsi, ini mengasumsikan detail tentang
UITableViewCell
yang belum pernah didokumentasikan Apple, seperti hierarki tampilan. Ini dapat diubah di masa mendatang, dan akibatnya kode di atas mungkin berperilaku tidak terduga.Sebagai hasil dari hal di atas, untuk alasan umur panjang dan keandalan, saya sarankan untuk mengadopsi pendekatan lain. Ada banyak alternatif yang tercantum di utas ini, dan saya mendorong Anda untuk membaca, tetapi favorit pribadi saya adalah sebagai berikut:
Pegang properti closure pada kelas sel Anda, minta metode aksi tombol memanggil ini.
Kemudian, saat Anda membuat sel
cellForRowAtIndexPath
, Anda dapat menetapkan nilai untuk closure Anda.Dengan memindahkan kode penangan Anda di sini, Anda dapat memanfaatkan
indexPath
argumen yang sudah ada . Ini adalah pendekatan yang jauh lebih aman daripada yang disebutkan di atas karena tidak bergantung pada sifat yang tidak terdokumentasi.sumber
Pendekatan saya untuk masalah semacam ini adalah dengan menggunakan protokol delegasi antara sel dan tampilan tabel. Hal ini memungkinkan Anda untuk mempertahankan penangan tombol dalam subkelas sel, yang memungkinkan Anda menetapkan penangan tindakan sentuhan ke sel prototipe di Pembuat Antarmuka, sambil tetap mempertahankan logika penangan tombol di pengontrol tampilan.
Ini juga menghindari pendekatan yang berpotensi rapuh dalam menavigasi hierarki tampilan atau penggunaan
tag
properti, yang memiliki masalah saat indeks sel berubah (sebagai akibat dari penyisipan, penghapusan, atau penyusunan ulang)CellSubclass.swift
ViewController.swift
sumber
buttonTapped
adalah fungsi delegasi dan dalam pengontrol tampilan. Dalam contoh saya,someButtonTapped
adalah metode tindakan dalam sel@IBAction func someButtonTapped(sender: UIButton) { self.delegate?.buttonTapped(self) }
UPDATE : Mendapatkan indexPath dari sel yang berisi tombol (bagian dan baris):
Menggunakan Posisi Tombol
Di dalam
buttonTapped
metode Anda, Anda dapat mengambil posisi tombol, mengubahnya menjadi koordinat di tableView, lalu mendapatkan indexPath dari baris pada koordinat tersebut.CATATAN : Kadang-kadang Anda bisa mengalami kasus tepi saat menggunakan
view.convert(CGPointZero, to:self.tableView)
hasil fungsi dalam menemukannil
baris pada suatu titik, meskipun ada sel tableView di sana. Untuk memperbaikinya, coba berikan koordinat nyata yang sedikit diimbangi dari asalnya, seperti:Jawaban Sebelumnya: Menggunakan Properti Tag (hanya mengembalikan baris)
Daripada naik ke pohon superview untuk mengambil penunjuk ke sel yang menahan tombol UIButton, ada teknik yang lebih aman dan dapat diulang dengan menggunakan properti button.tag yang disebutkan oleh Antonio di atas, dijelaskan dalam jawaban ini , dan ditunjukkan di bawah ini:
Di
cellForRowAtIndexPath:
Anda mengatur properti tag:Kemudian, dalam
buttonClicked:
fungsinya, Anda mereferensikan tag itu untuk mengambil baris indexPath tempat tombol berada:Saya lebih suka metode ini karena saya telah menemukan bahwa berayun di pohon superview bisa menjadi cara yang berisiko untuk mendesain aplikasi. Juga, untuk tujuan-C saya telah menggunakan teknik ini di masa lalu dan senang dengan hasilnya.
sumber
indexPath.section
tambahan keindexPath.row
(tanpa menyetel ulang properti tag sebagaiindexPath.section
), di dalamcellForRowAtIndexPath:
Anda cukup mengubah tag menjadibutton.tag = indexPath
, dan kemudian di dalambuttonClicked:
fungsi Anda bisa mengakses keduanya dengan menggunakansender.tag.row
dansender.tag.section
.Gunakan ekstensi ke UITableView untuk mengambil sel untuk tampilan apa pun:
Jawaban @ Paulw11 untuk menyiapkan tipe sel kustom dengan properti delegasi yang mengirim pesan ke tampilan tabel adalah cara yang baik untuk dilakukan, tetapi memerlukan sejumlah pekerjaan untuk menyiapkan.
Saya pikir menjalankan hierarki tampilan sel tampilan tabel mencari sel adalah ide yang buruk. Ini rapuh - jika nanti Anda mengapit tombol Anda dalam tampilan untuk tujuan tata letak, kode tersebut kemungkinan besar akan rusak.
Menggunakan tag tampilan juga rapuh. Anda harus ingat untuk menyiapkan tag saat Anda membuat sel, dan jika Anda menggunakan pendekatan itu dalam pengontrol tampilan yang menggunakan tag tampilan untuk tujuan lain, Anda dapat memiliki nomor tag duplikat dan kode Anda bisa gagal berfungsi seperti yang diharapkan.
Saya telah membuat ekstensi ke UITableView yang memungkinkan Anda mendapatkan indexPath untuk tampilan apa pun yang terdapat dalam sel tampilan tabel. Ini mengembalikan nilai
Optional
yang akan menjadi nol jika tampilan yang diteruskan sebenarnya tidak termasuk dalam sel tampilan tabel. Di bawah ini adalah file sumber ekstensi secara keseluruhan. Anda cukup meletakkan file ini di proyek Anda dan kemudian menggunakanindexPathForView(_:)
metode yang disertakan untuk menemukan indexPath yang berisi tampilan apa pun.Untuk menggunakannya, Anda cukup memanggil metode di IBAction untuk tombol yang ada di dalam sel:
(Perhatikan bahwa
indexPathForView(_:)
fungsi ini hanya akan berfungsi jika objek tampilan yang diteruskannya berisi sel yang saat ini ada di layar. Itu wajar, karena tampilan yang tidak ada di layar sebenarnya bukan milik indexPath tertentu; ditetapkan ke indexPath yang berbeda ketika itu berisi sel didaur ulang.)EDIT:
Anda dapat mengunduh proyek demo yang berfungsi yang menggunakan ekstensi di atas dari Github: TableViewExtension.git
sumber
Untuk
Swift2.1
Saya menemukan cara untuk melakukannya, semoga, ini akan membantu.
sumber
Anda memiliki tombol (myButton) atau tampilan lain di sel. Tetapkan tag di cellForRowAt seperti ini
Sekarang di Anda tapFungsi atau lainnya. Ambil seperti ini dan simpan dalam variabel lokal.
Setelah ini, Anda dapat menggunakan di mana saja currentCellNumber ini untuk mendapatkan indexPath.row dari tombol yang dipilih.
Nikmati!
sumber
Di Swift 4, cukup gunakan ini:
sumber
tableView
variabel outlet yang perlu direferensikan sebelum jawaban ini berfungsi.Sangat Sederhana mendapatkan Jalur Indeks 4, 5
Cara mendapatkan IndexPath Inside Btn Click:
sumber
Karena pengirim event handler adalah tombol itu sendiri, saya akan menggunakan
tag
properti tombol untuk menyimpan indeks, diinisialisasi dalamcellForRowAtIndexPath
.Tetapi dengan sedikit lebih banyak pekerjaan yang akan saya lakukan dengan cara yang sama sekali berbeda. Jika Anda menggunakan sel khusus, inilah cara saya mendekati masalahnya:
cellForRowAtIndexPath
sumber
Setelah melihat saran Paulw11 untuk menggunakan panggilan balik delegasi, saya ingin menguraikannya sedikit / mengajukan saran lain yang serupa. Jika Anda tidak ingin menggunakan pola delegasi, Anda dapat menggunakan closure dengan cepat sebagai berikut:
Kelas sel Anda:
cellForRowAtIndexPath
Metode Anda :sumber
Saya menemukan cara yang sangat mudah untuk digunakan untuk mengelola sel apa pun di tableView dan collectionView dengan menggunakan kelas Model dan ini berfungsi dengan sempurna.
Memang ada cara yang jauh lebih baik untuk menangani hal ini sekarang. Ini akan berfungsi untuk mengelola sel dan nilai.
Ini keluaran saya (tangkapan layar) jadi lihat ini:
RNCheckedModel
, tulis kodenya seperti dibawah ini.sumber
Saya menggunakan metode convertPoint untuk mendapatkan poin dari tableview dan meneruskan titik ini ke metode indexPathForRowAtPoint untuk mendapatkan indexPath
sumber
Coba gunakan #selector untuk memanggil IBaction.In cellforrowatindexpath
Dengan cara ini Anda dapat mengakses jalur indeks di dalam metode editButtonPressed
sumber
Dalam kasus saya, saya memiliki beberapa bagian dan indeks bagian dan baris sangat penting, jadi dalam kasus seperti itu saya baru saja membuat properti di UIButton yang saya atur sel indexPath seperti ini:
Kemudian setel properti di cellForRowAt seperti ini:
Kemudian di handleTapAction Anda bisa mendapatkan indexPath seperti ini:
sumber
Swift 4 dan 5
Metode 1 menggunakan delegasi protokol
Misalnya, Anda memiliki
UITableViewCell
dengan namaMyCell
Sekarang buat file
protocol
Langkah selanjutnya, buat Ekstensi
UITableView
Dalam
UIViewController
menerapkan protokol AndaMyCellDelegate
Metode 2 menggunakan penutupan
Di
UIViewController
sumber
Di Swift 3. Juga menggunakan pernyataan penjaga, menghindari kawat gigi yang panjang.
sumber
Terkadang tombol mungkin berada di dalam tampilan lain UITableViewCell. Dalam hal ini superview.superview mungkin tidak memberikan objek sel dan karenanya indexPath akan menjadi nihil.
Dalam hal ini kita harus terus mencari superview sampai kita mendapatkan objek selnya.
Berfungsi untuk mendapatkan objek sel melalui superview
Sekarang kita bisa mendapatkan indexPath dengan menekan tombol seperti di bawah ini
sumber
sumber