Jawaban:
Anda mencari solusi ini:
StaticDataTableViewController 2.0
https://github.com/xelvenone/StaticDataTableViewController
yang dapat menampilkan / menyembunyikan / memuat ulang sel statis apa pun dengan atau tanpa animasi!
[self cell:self.outletToMyStaticCell1 setHidden:hide];
[self cell:self.outletToMyStaticCell2 setHidden:hide];
[self reloadDataAnimated:YES];
Catatan untuk selalu menggunakan saja (reloadDataAnimated: YES / NO) (jangan panggil [self.tableView reloadData] secara langsung)
Ini tidak menggunakan solusi peretasan dengan menetapkan tinggi ke 0 dan memungkinkan Anda untuk menghidupkan perubahan dan menyembunyikan seluruh bagian
IBOutletCollection
tetapi saya tidak melihat bagaimana itu akan membuat perbedaan. Saya hanya mengunduh kode kemarin jadi saya rasa ini bukan versi lama.
Untuk menyembunyikan sel statis di UITable:
Di kelas delegasi kontroler UITableView Anda:
Tujuan-C:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if(cell == self.cellYouWantToHide)
return 0; //set the hidden cell's height to 0
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
Cepat:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
var cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)
if cell == self.cellYouWantToHide {
return 0
}
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
Metode ini akan dipanggil untuk setiap sel dalam UITable. Setelah ia memanggilnya untuk sel yang ingin Anda sembunyikan, kami mengatur ketinggiannya ke 0. Kami mengidentifikasi sel target dengan membuat outlet untuknya:
ClipToBounds
masalah ini, Anda juga dapat mengatur sel ke tersembunyi. Bagi saya ini tampak lebih bersih. ;-)
Cara terbaik adalah seperti yang dijelaskan dalam blog berikut ini http://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/
Rancang tampilan tabel statis Anda seperti biasa di pembuat antarmuka - lengkap dengan semua sel yang berpotensi tersembunyi. Tetapi ada satu hal yang harus Anda lakukan untuk setiap sel potensial yang ingin Anda sembunyikan - periksa properti “Klip tayangan balik” sel, jika tidak, isi sel tidak hilang ketika Anda mencoba dan menyembunyikannya (dengan mengecilkan tingginya) - nanti lagi).
SO - Anda memiliki sakelar di sel dan sakelar itu seharusnya menyembunyikan dan menampilkan beberapa sel statis. Menghubungkannya ke IBAction dan di sana lakukan ini:
[self.tableView beginUpdates]; [self.tableView endUpdates];
Itu memberi Anda animasi yang bagus untuk sel yang muncul dan menghilang. Sekarang terapkan metode delegasi tampilan tabel berikut:
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 1 && indexPath.row == 1) { // This is the cell to hide - change as you need // Show or hide cell if (self.mySwitch.on) { return 44; // Show the cell - adjust the height as you need } else { return 0; // Hide the cell } } return 44; }
Dan itu saja. Balik saklar dan selnya bersembunyi dan muncul kembali dengan animasi yang bagus dan halus.
Solusi saya menuju ke arah yang sama seperti Gareth, meskipun saya melakukan beberapa hal secara berbeda.
Ini dia:
1. Sembunyikan sel
Tidak ada cara untuk menyembunyikan sel secara langsung. UITableViewController
adalah sumber data yang menyediakan sel statis, dan saat ini tidak ada cara untuk mengatakannya "tidak menyediakan sel x". Jadi kita harus menyediakan sumber data kita sendiri, yang didelegasikan kepada UITableViewController
untuk mendapatkan sel statis.
Paling mudah adalah dengan subkelas UITableViewController
, dan menimpa semua metode yang perlu berperilaku berbeda saat menyembunyikan sel .
Dalam kasus paling sederhana (tabel satu bagian, semua sel memiliki ketinggian yang sama), ini akan seperti ini:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [super tableView:tableView numberOfRowsInSection:section] - numberOfCellsHidden;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Recalculate indexPath based on hidden cells
indexPath = [self offsetIndexPath:indexPath];
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
- (NSIndexPath*)offsetIndexPath:(NSIndexPath*)indexPath
{
int offsetSection = indexPath.section; // Also offset section if you intend to hide whole sections
int numberOfCellsHiddenAbove = ... // Calculate how many cells are hidden above the given indexPath.row
int offsetRow = indexPath.row + numberOfCellsHiddenAbove;
return [NSIndexPath indexPathForRow:offsetRow inSection:offsetSection];
}
Jika tabel Anda memiliki beberapa bagian, atau sel memiliki ketinggian yang berbeda, Anda perlu mengganti metode lainnya. Prinsip yang sama berlaku di sini: Anda perlu mengimbangi indexPath, bagian dan baris sebelum mendelegasikan ke super.
Juga perlu diingat bahwa parameter indexPath untuk metode seperti didSelectRowAtIndexPath:
akan berbeda untuk sel yang sama, tergantung pada keadaan (yaitu jumlah sel yang disembunyikan). Jadi mungkin ide yang bagus untuk selalu mengimbangi parameter indexPath dan bekerja dengan nilai-nilai ini.
2. Buat animasi perubahan
Seperti yang sudah dinyatakan Gareth, Anda mendapatkan gangguan besar jika Anda menghidupkan perubahan menggunakan reloadSections:withRowAnimation:
metode.
Saya menemukan bahwa jika Anda menelepon reloadData:
segera setelah itu, animasinya jauh lebih baik (hanya gangguan kecil yang tersisa). Tabel ditampilkan dengan benar setelah animasi.
Jadi yang saya lakukan adalah:
- (void)changeState
{
// Change state so cells are hidden/unhidden
...
// Reload all sections
NSIndexSet* reloadSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self numberOfSectionsInTableView:tableView])];
[tableView reloadSections:reloadSet withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView reloadData];
}
numberOfRowsInSection:
- sel statis dipanggil hanya ketika tabel memuat pertama kali. Ketika saya memanggil [self.tableView reloadData] - numberOfRowsInSection:
tidak pernah dipanggil lagi. Hanya cellForRowAtIndexPath:
dipanggil. Apa yang saya lewatkan?
cellOneOutlet.hidden = true
sekarang ganti metode di bawah ini, periksa status sel mana yang disembunyikan dan kembalikan tinggi 0 untuk sel-sel itu. Ini adalah salah satu dari banyak cara Anda dapat menyembunyikan sel apa pun di tabel statis dengan cepat.
override func tableView(tableView: UITableView, heightForRowAtIndexPathindexPath: NSIndexPath) -> CGFloat
{
let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)
if tableViewCell.hidden == true
{
return 0
}
else{
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
}
let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)
. Saya menganggap itu diganti oleh let tableViewCell = tableView.cellForRow(at: indexPath as IndexPath)
.
UITableViewController
, saya tidak punya UITableView
metode delegasi. Untuk dapat menelepon heightForRow
, apakah saya perlu memiliki metode lain juga?
Saya datang dengan alternatif yang sebenarnya menyembunyikan bagian dan tidak menghapusnya. Saya mencoba pendekatan @ henning77, tetapi saya terus mengalami masalah ketika saya mengubah jumlah bagian dari UITableView statis. Metode ini telah bekerja dengan sangat baik untuk saya, tetapi saya terutama berusaha menyembunyikan bagian daripada baris. Saya berhasil menghapus beberapa baris dengan cepat, tetapi jauh lebih berantakan, jadi saya sudah mencoba untuk mengelompokkan beberapa hal menjadi bagian yang perlu saya perlihatkan atau sembunyikan. Berikut adalah contoh bagaimana saya menyembunyikan bagian:
Pertama saya mendeklarasikan properti NSMutableArray
@property (nonatomic, strong) NSMutableArray *hiddenSections;
Di viewDidLoad (atau setelah Anda menanyakan data Anda), Anda bisa menambahkan bagian yang ingin Anda sembunyikan ke array.
- (void)viewDidLoad
{
hiddenSections = [NSMutableArray new];
if(some piece of data is empty){
// Add index of section that should be hidden
[self.hiddenSections addObject:[NSNumber numberWithInt:1]];
}
... add as many sections to the array as needed
[self.tableView reloadData];
}
Kemudian mengimplementasikan metode delegasi TableView berikut
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
return nil;
}
return [super tableView:tableView titleForHeaderInSection:section];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
return 0;
}
return [super tableView:tableView heightForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
[cell setHidden:YES];
}
}
Kemudian atur tinggi header dan footer ke 1 untuk bagian tersembunyi karena Anda tidak dapat mengatur tinggi ke 0. Ini menyebabkan ruang 2 pixel tambahan, tetapi kita bisa menebusnya dengan menyesuaikan ketinggian header yang terlihat berikutnya.
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
CGFloat height = [super tableView:tableView heightForHeaderInSection:section];
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
height = 1; // Can't be zero
}
else if([self tableView:tableView titleForHeaderInSection:section] == nil){ // Only adjust if title is nil
// Adjust height for previous hidden sections
CGFloat adjust = 0;
for(int i = (section - 1); i >= 0; i--){
if([self.hiddenSections containsObject:[NSNumber numberWithInt:i]]){
adjust = adjust + 2;
}
else {
break;
}
}
if(adjust > 0)
{
if(height == -1){
height = self.tableView.sectionHeaderHeight;
}
height = height - adjust;
if(height < 1){
height = 1;
}
}
}
return height;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
return 1;
}
return [super tableView:tableView heightForFooterInSection:section];
}
Kemudian, jika Anda memiliki baris tertentu untuk disembunyikan Anda dapat menyesuaikan numberOfRowsInSection dan baris mana yang dikembalikan di cellForRowAtIndexPath. Dalam contoh ini di sini saya memiliki bagian yang memiliki tiga baris di mana tiga bisa kosong dan perlu dihapus.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = [super tableView:tableView numberOfRowsInSection:section];
if(self.organization != nil){
if(section == 5){ // Contact
if([self.organization objectForKey:@"Phone"] == [NSNull null]){
rows--;
}
if([self.organization objectForKey:@"Email"] == [NSNull null]){
rows--;
}
if([self.organization objectForKey:@"City"] == [NSNull null]){
rows--;
}
}
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [super tableView:tableView cellForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}
Gunakan offsetIndexPath ini untuk menghitung indexPath untuk baris tempat Anda menghapus baris secara kondisional. Tidak diperlukan jika Anda hanya menyembunyikan bagian
- (NSIndexPath *)offsetIndexPath:(NSIndexPath*)indexPath
{
int row = indexPath.row;
if(self.organization != nil){
if(indexPath.section == 5){
// Adjust row to return based on which rows before are hidden
if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){
row++;
}
else if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Address"] != [NSNull null]){
row = row + 2;
}
else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] != [NSNull null] && [self.organization objectForKey:@"Email"] == [NSNull null]){
row++;
}
else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){
row++;
}
}
}
NSIndexPath *offsetPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section];
return offsetPath;
}
Ada banyak metode untuk ditimpa, tetapi apa yang saya sukai dari pendekatan ini adalah bahwa itu dapat digunakan kembali. Atur array hiddenSections, tambahkan padanya, dan itu akan menyembunyikan bagian yang benar. Menyembunyikan barisnya sedikit lebih sulit, tapi mungkin. Kami tidak bisa hanya mengatur ketinggian baris yang ingin kami sembunyikan menjadi 0 jika kami menggunakan UITableView yang dikelompokkan karena batas tidak akan dapat digambarkan dengan benar.
NSMutableSet
untuk hiddenSections
gantinya. Ini jauh lebih cepat karena Anda kebanyakan menguji keanggotaan.
NSMutableSet
untuk hiddenSections
, meskipun saya mengerti bahwa titik jawaban Anda lebih konseptual daripada rewel tentang jenis struktur data yang harus Anda gunakan.
Ternyata, Anda dapat menyembunyikan dan menampilkan sel dalam UITableView statis - dan dengan animasi. Dan itu tidak terlalu sulit untuk dicapai.
Intinya:
Use tableView:heightForRowAtIndexPath:
untuk menentukan ketinggian sel secara dinamis berdasarkan pada beberapa keadaan.tableView.beginUpdates();tableView.endUpdates()
tableView.cellForRowAtIndexPath:
dalam tableView:heightForRowAtIndexPath:
. Gunakan indexPath yang di-cache untuk membedakan sel.Ya, itu pasti mungkin, meskipun saya sedang berjuang dengan masalah yang sama saat ini. Saya telah berhasil membuat sel-selnya disembunyikan dan semuanya berfungsi dengan baik, tetapi saat ini saya tidak dapat membuat benda itu hidup dengan rapi. Inilah yang saya temukan:
Saya menyembunyikan baris berdasarkan status sakelar HIDUP / MATI di baris pertama bagian pertama. Jika sakelar HIDUP ada 1 baris di bawahnya di bagian yang sama, jika tidak ada 2 baris yang berbeda.
Saya memiliki pemilih yang dipanggil saat sakelar diaktifkan, dan saya menetapkan variabel untuk menunjukkan keadaan saya saat ini. Lalu saya menelepon:
[[self tableView] reloadData];
Saya mengganti fungsi tableView: willDisplayCell: forRowAtIndexPath: dan jika sel seharusnya disembunyikan saya melakukan ini:
[cell setHidden:YES];
Itu menyembunyikan sel dan isinya, tetapi tidak menghilangkan ruang yang didudukinya.
Untuk menghapus spasi, timpa fungsi tableView: heightForRowAtIndexPath: dan kembalikan 0 untuk baris yang harus disembunyikan.
Anda juga perlu mengganti tableView: numberOfRowsInSection: dan mengembalikan jumlah baris di bagian itu. Anda harus melakukan sesuatu yang aneh di sini sehingga jika meja Anda adalah gaya yang dikelompokkan sudut-sudut bulat terjadi pada sel yang benar. Dalam tabel statis saya ada set lengkap sel untuk bagian tersebut, jadi ada sel pertama yang berisi opsi, lalu 1 sel untuk opsi status ON dan 2 sel lagi untuk opsi status MATI, total 4 sel. Ketika opsi ON, saya harus mengembalikan 4, ini termasuk opsi tersembunyi sehingga opsi terakhir yang ditampilkan memiliki kotak bulat. Ketika opsi mati, dua opsi terakhir tidak ditampilkan jadi saya kembali 2. Ini semua terasa kikuk. Maaf jika ini tidak terlalu jelas, sulit dijelaskan. Hanya untuk mengilustrasikan pengaturan, ini adalah konstruksi bagian tabel di IB:
Jadi ketika opsi ON tabel melaporkan dua baris yaitu:
Ketika opsi MATI, tabel melaporkan empat baris yaitu:
Pendekatan ini tidak terasa benar karena beberapa alasan, sejauh yang saya dapatkan dengan eksperimen saya sejauh ini, jadi tolong beri tahu saya jika Anda menemukan cara yang lebih baik. Masalah yang saya amati sejauh ini adalah:
Rasanya salah mengatakan tabel jumlah baris berbeda dengan apa yang mungkin terkandung dalam data yang mendasarinya.
Sepertinya saya tidak bisa menghidupkan perubahan. Saya sudah mencoba menggunakan tableView: reloadSections: withRowAnimation: alih-alih reloadData dan hasilnya sepertinya tidak masuk akal, saya masih mencoba membuatnya berfungsi. Saat ini yang tampaknya terjadi adalah tableView tidak memperbarui baris yang benar sehingga satu tetap tersembunyi yang harus ditampilkan dan kekosongan ditinggalkan di bawah baris pertama. Saya pikir ini mungkin terkait dengan poin pertama tentang data yang mendasarinya.
Semoga seseorang akan dapat menyarankan metode alternatif atau mungkin cara memperluas dengan animasi, tetapi mungkin ini akan membantu Anda memulai. Saya minta maaf karena kurangnya hyperlink ke fungsi, saya masukkan tetapi mereka ditolak oleh filter spam karena saya adalah pengguna yang cukup baru.
[[self tableView] reloadData];
sekali lagi setelah menyembunyikan sel
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
di UITableViewController
subclass untuk menciptakan sel statis. Jalur indeks diindeks statis - tidak dinamis ...
Sesuai jawaban Justas, tetapi untuk Swift 4:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = super.tableView(tableView, cellForRowAt: indexPath)
if cell == self.cellYouWantToHide {
return 0
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
tableView.reloadRows(at:, with:)
memperbarui sel jika Anda mengubah ketinggian saat baris sudah terlihat.
Oke, setelah mencoba, saya punya jawaban yang tidak umum. Saya menggunakan variabel "isHidden" atau "hidden" untuk memeriksa apakah sel ini harus disembunyikan.
buat IBOutlet ke pengontrol tampilan Anda.
@IBOutlet weak var myCell: UITableViewCell!
Perbarui myCell
fungsi kustom Anda, misalnya Anda dapat menambahkannya di viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
self.myCell.isHidden = true
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = super.tableView(tableView, cellForRowAt: indexPath)
guard !cell.isHidden else {
return 0
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
Ini akan mengurangi logika Anda dalam metode delegasi, dan Anda hanya perlu fokus pada kebutuhan bisnis Anda.
Jawaban di atas yang menyembunyikan / menampilkan sel, mengubah rowHeight, atau mengacaukan dengan batasan tata letak otomatis tidak berfungsi untuk saya karena masalah tata letak otomatis. Kode menjadi tidak tertahankan.
Untuk tabel statis sederhana, yang paling berhasil bagi saya adalah:
Ini adalah contoh dari pengontrol tampilan tabel saya:
@IBOutlet weak var titleCell: UITableViewCell!
@IBOutlet weak var nagCell: UITableViewCell!
@IBOutlet weak var categoryCell: UITableViewCell!
var cellsToShow: [UITableViewCell] = []
override func viewDidLoad() {
super.viewDidLoad()
determinCellsToShow()
}
func determinCellsToShow() {
if detail!.duration.type != nil {
cellsToShow = [titleCell, nagCell, categoryCell]
}
else {
cellsToShow = [titleCell, categoryCell]
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return cellsToShow[indexPath.row]
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellsToShow.count
}
Untuk iOS 11, saya menemukan bahwa versi modifikasi dari jawaban Mohamed Saleh bekerja paling baik, dengan beberapa perbaikan berdasarkan dokumentasi Apple. Ia menjiwai dengan baik, menghindari peretasan yang jelek atau nilai yang di-hardcoded, dan menggunakan ketinggian baris yang telah ditetapkan dalam Interface Builder .
Konsep dasarnya adalah mengatur tinggi baris ke 0 untuk setiap baris tersembunyi. Kemudian gunakan tableView.performBatchUpdates
untuk memicu animasi yang bekerja secara konsisten.
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath == indexPathOfHiddenCell {
if cellIsHidden {
return 0
}
}
// Calling super will use the height set in your storyboard, avoiding hardcoded values
return super.tableView(tableView, heightForRowAt: indexPath)
}
Anda akan ingin memastikan cellIsHidden
dan indexPathOfHiddenCell
diatur sesuai dengan kasus penggunaan Anda. Untuk kode saya mereka adalah properti pada pengontrol tampilan tabel saya.
Dalam metode apa pun yang mengontrol visibilitas (kemungkinan aksi tombol atau didSelectRow
), alihkan keadaan cellIsHidden, di dalam performBatchUpdates
blok:
tableView.performBatchUpdates({
// Use self to capture for block
self.cellIsHidden = !self.cellIsHidden
}, completion: nil)
Apple merekomendasikan performBatchUpdates
lebih dari beginUpdates
/endUpdates
kapan pun memungkinkan.
Saya menemukan solusi untuk menghidupkan sel bersembunyi di tabel statis.
// Class for wrapping Objective-C block
typedef BOOL (^HidableCellVisibilityFunctor)();
@interface BlockExecutor : NSObject
@property (strong,nonatomic) HidableCellVisibilityFunctor block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block;
@end
@implementation BlockExecutor
@synthesize block = _block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block
{
BlockExecutor * executor = [[BlockExecutor alloc] init];
executor.block = block;
return executor;
}
@end
Hanya satu kamus tambahan yang dibutuhkan:
@interface MyTableViewController ()
@property (nonatomic) NSMutableDictionary * hidableCellsDict;
@property (weak, nonatomic) IBOutlet UISwitch * birthdaySwitch;
@end
Dan lihat implementasi MyTableViewController. Kami membutuhkan dua metode untuk mengonversi indexPath antara indeks yang terlihat dan tidak terlihat ...
- (NSIndexPath*)recoverIndexPath:(NSIndexPath *)indexPath
{
int rowDelta = 0;
for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
if (ip.section == indexPath.section
&& ip.row <= indexPath.row + rowDelta
&& !executor.block())
{
rowDelta++;
}
}
return [NSIndexPath indexPathForRow:indexPath.row+rowDelta inSection:indexPath.section];
}
- (NSIndexPath*)mapToNewIndexPath:(NSIndexPath *)indexPath
{
int rowDelta = 0;
for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
if (ip.section == indexPath.section
&& ip.row < indexPath.row - rowDelta
&& !executor.block())
{
rowDelta++;
}
}
return [NSIndexPath indexPathForRow:indexPath.row-rowDelta inSection:indexPath.section];
}
Satu IBAction pada perubahan nilai UISwitch:
- (IBAction)birthdaySwitchChanged:(id)sender
{
NSIndexPath * indexPath = [self mapToNewIndexPath:[NSIndexPath indexPathForRow:1 inSection:1]];
if (self.birthdaySwitch.on)
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
else
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
Beberapa metode UITableViewDataSource dan UITableViewDelegate:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int numberOfRows = [super tableView:tableView numberOfRowsInSection:section];
for (NSIndexPath * indexPath in [self.hidableCellsDict allKeys])
if (indexPath.section == section)
{
BlockExecutor * executor = [self.hidableCellsDict objectForKey:indexPath];
numberOfRows -= (executor.block()?0:1);
}
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
indexPath = [self recoverIndexPath:indexPath];
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
indexPath = [self recoverIndexPath:indexPath];
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// initializing dictionary
self.hidableCellsDict = [NSMutableDictionary dictionary];
[self.hidableCellsDict setObject:[BlockExecutor executorWithBlock:^(){return self.birthdaySwitch.on;}] forKey:[NSIndexPath indexPathForRow:1 inSection:1]];
}
- (void)viewDidUnload
{
[self setBirthdaySwitch:nil];
[super viewDidUnload];
}
@end
Jawab dengan cepat :
Tambahkan metode berikut di TableViewController Anda:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return indexPathOfCellYouWantToHide == indexPath ? 0 : super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
jika tableView mencoba menggambar sel yang ingin Anda sembunyikan, maka ia tidak akan menampilkannya karena tingginya akan diatur ke 0pt berkat metode di atas, semua yang lain tetap tidak berubah.
Harap dicatat bahwa indexPathOfCellYouWantToHide
dapat diubah kapan saja :)
Di> Swift 2.2, saya telah menggabungkan beberapa jawaban di sini.
Buat saluran keluar dari storyboard untuk menautkan ke staticCell Anda.
@IBOutlet weak var updateStaticCell: UITableViewCell!
override func viewDidLoad() {
...
updateStaticCell.hidden = true
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 0 {
return 0
} else {
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
}
Saya ingin menyembunyikan sel pertama saya sehingga saya mengatur ketinggian ke 0 seperti dijelaskan di atas.
Swift 4:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var height = super.tableView(tableView, heightForRowAt: indexPath)
if (indexPath.row == HIDDENROW) {
height = 0.0
}
return height
}
Untuk skenario termudah ketika Anda menyembunyikan sel di bagian paling bawah tampilan tabel, Anda bisa menyesuaikan contentInset tableView setelah Anda menyembunyikan sel:
- (void)adjustBottomInsetForHiddenSections:(NSInteger)numberOfHiddenSections
{
CGFloat bottomInset = numberOfHiddenSections * 44.0; // or any other 'magic number
self.tableView.contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, self.tableView.contentInset.left, -bottomInset, self.tableView.contentInset.right);
}
Ini adalah cara baru untuk melakukan ini menggunakan https://github.com/k06a/ABStaticTableViewController
NSIndexPath *ip = [NSIndexPath indexPathForRow:1 section:1];
[self deleteRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationFade]
Solusi dari k06a ( https://github.com/k06a/ABStaticTableViewController ) lebih baik karena menyembunyikan seluruh bagian termasuk header dan footer sel, di mana solusi ini ( https://github.com/peterpaulis/StaticDataTableViewController ) menyembunyikan semuanya kecuali footer.
EDIT
Saya baru saja menemukan solusi jika Anda ingin menyembunyikan catatan kaki StaticDataTableViewController
. Ini yang perlu Anda salin dalam file StaticTableViewController.m:
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
return nil;
} else {
return [super tableView:tableView titleForFooterInSection:section];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
CGFloat height = [super tableView:tableView heightForFooterInSection:section];
if (self.originalTable == nil) {
return height;
}
if (!self.hideSectionsWithHiddenRows) {
return height;
}
OriginalSection * os = self.originalTable.sections[section];
if ([os numberOfVissibleRows] == 0) {
//return 0;
return CGFLOAT_MIN;
} else {
return height;
}
//return 0;
return CGFLOAT_MIN;
}
Tentunya kamu bisa. Pertama, kembalilah ke tableView Anda jumlah sel yang ingin Anda tampilkan lalu panggil super
untuk mencapai sel tertentu dari storyboard Anda dan kembalikan untuk tableView:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.mode.numberOfCells()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))
return cell
}
Jika sel Anda memiliki hieght yang berbeda, kembalikan juga:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return super.tableView(tableView, heightForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))
}
Selain solusi @Saleh Masum:
Jika Anda mendapatkan kesalahan tata letak otomatis , Anda bisa menghapus batasan daritableViewCell.contentView
Swift 3:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let tableViewCell = super.tableView(tableView, cellForRowAt: indexPath)
if tableViewCell.isHidden == true
{
tableViewCell.contentView.removeConstraints(tableViewCell.contentView.constraints)
return 0
}
else{
return super.tableView(tableView, heightForRowAt: indexPath)
}
}
Solusi ini tergantung pada aliran aplikasi Anda . Jika Anda ingin menampilkan / menyembunyikan sel dalam instance controller tampilan yang sama, ini mungkin bukan pilihan terbaik, karena menghilangkan kendala .
Saya mendapatkan cara yang lebih baik untuk menyembunyikan sel statis dan bahkan bagian secara dinamis tanpa ada peretasan.
Mengatur tinggi baris ke 0 dapat menyembunyikan baris, tetapi itu tidak berfungsi jika Anda ingin menyembunyikan seluruh bagian yang akan menampung beberapa spasi bahkan Anda menyembunyikan semua baris.
Pendekatan saya adalah untuk membangun bagian array sel statis. Maka isi tampilan tabel akan didorong oleh array bagian.
Berikut ini beberapa contoh kode:
var tableSections = [[UITableViewCell]]()
private func configTableSections() {
// seciton A
tableSections.append([self.cell1InSectionA, self.cell2InSectionA])
// section B
if shouldShowSectionB {
tableSections.append([self.cell1InSectionB, self.cell2InSectionB])
}
// section C
if shouldShowCell1InSectionC {
tableSections.append([self.cell1InSectionC, self.cell2InSectionC, self.cell3InSectionC])
} else {
tableSections.append([self.cell2InSectionC, self.cell3InSectionC])
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return tableSections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableSections[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return tableSections[indexPath.section][indexPath.row]
}
Dengan cara ini, Anda dapat menyatukan semua kode konfigurasi tanpa harus menulis kode jahat untuk menghitung jumlah baris dan bagian. Dan tentu saja tidak0
ketinggian lagi.
Kode ini juga sangat mudah dipelihara. Misalnya, jika Anda ingin menambah / menghapus lebih banyak sel atau bagian.
Demikian pula, Anda dapat membuat larik judul tajuk bagian dan larik judul tajuk bagian untuk mengonfigurasi judul bagian Anda secara dinamis.