Saya merasa seperti ini mungkin menjadi masalah umum dan bertanya-tanya apakah ada solusi umum untuk itu.
Pada dasarnya, UITableView saya memiliki ketinggian sel dinamis untuk setiap sel. Jika saya tidak berada di bagian atas UITableView dan saya tableView.reloadData()
, menggulir ke atas menjadi gelisah.
Saya percaya ini karena fakta bahwa karena saya memuat ulang data, saat saya menggulir ke atas, UITableView menghitung ulang ketinggian untuk setiap sel yang terlihat. Bagaimana cara mengurangi itu, atau bagaimana saya hanya reloadData dari IndexPath tertentu ke akhir UITableView?
Selanjutnya, ketika saya berhasil menggulir ke atas, saya dapat menggulir ke bawah dan ke atas, tidak ada masalah tanpa melompat. Ini kemungkinan besar karena ketinggian UITableViewCell sudah dihitung.
sumber
reloadRowsAtIndexPaths
. Tetapi (2) apa yang Anda maksud dengan "gelisah" dan (3) sudahkah Anda menetapkan tinggi baris yang diperkirakan? (Hanya mencoba mencari tahu apakah ada solusi yang lebih baik yang akan memungkinkan Anda untuk memperbarui tabel secara dinamis.)x
ke baris terakhir di TableView saya ... tetapi karena saya memasukkan baris baru, itu tidak akan berfungsi, saya tidak bisa tahu apa ujung tampilan tabel saya sebelum saya memuat ulang data.Jawaban:
Untuk mencegah lompatan, Anda harus menyimpan ketinggian sel saat memuat dan memberikan nilai tepat dalam
tableView:estimatedHeightForRowAtIndexPath
:Cepat:
Sasaran C:
sumber
cellHeightsDictionary
:cellHeightsDictionary = [NSMutableDictionary dictionary];
estimatedHeightForRowAtIndexPath:
mengembalikan nilai ganda dapat menyebabkan*** Assertion failure in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]
kesalahan. Untuk memperbaikinya,return floorf(height.floatValue);
sebagai gantinya.Swift 3 versi jawaban yang diterima.
sumber
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
, ini menangani semua perhitungan ketinggian yang saya butuhkan.UITableViewDelegate
ke kelas saya. Sesuai dengan protokol itu diperlukan karena mengandungwillDisplay
fungsi yang ditunjukkan di atas . Saya harap saya bisa menyelamatkan seseorang dari perjuangan yang sama.Lompatan ini karena perkiraan ketinggian yang buruk. Semakin tinggi taksiranRowHeight berbeda dari ketinggian sebenarnya, semakin banyak tabel dapat melompat ketika dimuat ulang terutama semakin jauh ke bawah telah digulir. Ini karena ukuran perkiraan tabel secara radikal berbeda dari ukuran sebenarnya, memaksa tabel untuk menyesuaikan ukuran kontennya dan offset. Jadi estimasi ketinggian seharusnya bukan nilai acak, tetapi mendekati apa yang Anda pikirkan ketinggiannya. Saya juga pernah mengalami ketika saya mengatur
UITableViewAutomaticDimension
apakah sel Anda adalah tipe yang samajika Anda memiliki berbagai sel di berbagai bagian maka saya pikir tempat yang lebih baik adalah
sumber
tableView(_:estimatedHeightForHeaderInSection:)
@ Igor menjawab berfungsi dengan baik dalam hal ini,
Swift-4
kode itu.dalam metode berikut
UITableViewDelegate
sumber
Saya sudah mencoba semua solusi di atas, tetapi tidak ada yang berhasil.
Setelah menghabiskan berjam-jam dan melalui semua frustrasi yang mungkin, menemukan cara untuk memperbaikinya. Solusi ini adalah penyelamat hidup! Bekerja seperti pesona!
Cepat 4
Saya menambahkannya sebagai ekstensi, untuk membuat kode terlihat lebih bersih dan menghindari penulisan semua baris ini setiap kali saya ingin memuat ulang.
akhirnya ..
ATAU Anda benar-benar dapat menambahkan baris ini dalam
UITableViewCell
awakeFromNib()
metode Andadan lakukan normal
reloadData()
sumber
reloadWithoutAnimation
tapi di manareload
bagian?tableView.reloadData()
dulu dan kemudiantableView.reloadWithoutAnimation()
, masih berfungsi.Saya menggunakan lebih banyak cara untuk memperbaikinya:
Untuk pengontrol tampilan:
sebagai ekstensi untuk UITableView
Hasilnya adalah
sumber
Saya mengalami ini hari ini dan mengamati:
cellForRowAtIndexPath
tidak membantu.Cara mengatasinya sebenarnya cukup sederhana:
Timpa
estimatedHeightForRowAtIndexPath
dan pastikan mengembalikan nilai yang benar.Dengan ini, semua kegugupan dan lompatan aneh di UITableViews saya telah berhenti.
CATATAN: Saya benar-benar tahu ukuran sel saya. Hanya ada dua nilai yang mungkin. Jika sel Anda benar-benar berukuran variabel, maka Anda mungkin ingin men-cache
cell.bounds.size.height
daritableView:willDisplayCell:forRowAtIndexPath:
sumber
Anda sebenarnya hanya bisa memuat ulang baris tertentu dengan menggunakan
reloadRowsAtIndexPaths
, mis:Namun, secara umum, Anda juga bisa menghidupkan perubahan tinggi sel tabel seperti:
sumber
Ini versi yang sedikit lebih pendek:
sumber
Mengganti metode estimasiHeightForRowAtIndexPath dengan nilai tinggi, misalnya 300f
Ini harus memperbaiki masalah :)
sumber
Ada bug yang saya percaya diperkenalkan di iOS11.
Saat itulah Anda melakukan
reload
tableView secaracontentOffSet
tak terduga diubah. BahkancontentOffset
seharusnya tidak berubah setelah memuat ulang. Ini cenderung terjadi karena kesalahan perhitunganUITableViewAutomaticDimension
Anda harus menyimpan
contentOffSet
dan menyetelnya kembali ke nilai yang disimpan setelah memuat ulang.Bagaimana Anda menggunakannya?
Jawaban ini berasal dari sini
sumber
Yang ini bekerja untuk saya di Swift4:
sumber
Tidak ada solusi yang berhasil untuk saya. Inilah yang saya lakukan dengan Swift 4 & Xcode 10.1 ...
Di viewDidLoad (), deklarasikan tinggi baris dinamis tabel dan buat batasan yang benar dalam sel ...
Juga di viewDidLoad (), daftarkan semua nibs sel tableView Anda ke tableview seperti ini:
Di tableView heightForRowAt, kembalikan tinggi sama dengan tinggi setiap sel di indexPath.row ...
Sekarang berikan tinggi baris perkiraan untuk setiap sel di tableView estimasiHeightForRowAt. Jadilah seakurat mungkin ...
Itu seharusnya bekerja ...
Saya tidak perlu menyimpan dan mengatur contentOffset saat memanggil tableView.reloadData ()
sumber
Saya memiliki 2 ketinggian sel yang berbeda.
Setelah saya menambahkan estimasiHeightForRowAt , tidak ada lagi lompatan.
sumber
Cobalah menelepon
cell.layoutSubviews()
sebelum mengembalikan selfunc cellForRowAtIndexPath(_ indexPath: NSIndexPath) -> UITableViewCell?
. Ini bug yang dikenal di iOS8.sumber
Anda dapat menggunakan yang berikut ini di
ViewDidLoad()
sumber
Saya memiliki perilaku lompatan ini dan pada awalnya saya dapat menguranginya dengan menetapkan perkiraan tinggi tajuk yang tepat (karena saya hanya memiliki 1 kemungkinan tampilan tajuk), namun lompatan kemudian mulai terjadi di dalam tajuk secara khusus, tidak memengaruhi seluruh tabel lagi.
Mengikuti jawaban di sini, saya memiliki petunjuk bahwa itu terkait dengan animasi, jadi saya menemukan bahwa tampilan tabel ada di dalam tampilan tumpukan, dan kadang-kadang kita akan memanggil
stackView.layoutIfNeeded()
di dalam blok animasi. Solusi terakhir saya adalah memastikan panggilan ini tidak terjadi kecuali "benar-benar" diperlukan, karena tata letak "jika diperlukan" memiliki perilaku visual dalam konteks itu bahkan ketika "tidak diperlukan".sumber
Saya memiliki masalah yang sama. Saya memiliki pagination dan memuat ulang data tanpa animasi tetapi tidak membantu gulir untuk mencegah melompat. Saya memiliki ukuran iPhone yang berbeda, gulungannya tidak gelisah pada iphone8 tetapi gelisah pada iphone7 +
Saya menerapkan perubahan berikut pada fungsi viewDidLoad :
dan masalah saya terpecahkan. Saya harap ini membantu Anda juga.
sumber
Salah satu pendekatan untuk memecahkan masalah ini yang saya temukan adalah
sumber
Sebenarnya saya menemukan jika Anda menggunakan
reloadRows
menyebabkan masalah melompat. Maka Anda harus mencoba menggunakanreloadSections
seperti ini:sumber