UITableView ustawia statyczne komórki. Czy można programowo ukryć niektóre komórki?

UITableView Ustaw na komórki statyczne.

Czy można programowo ukryć niektóre komórki?

Author: jszumski, 2011-11-24

20 answers

Szukasz tego rozwiązania:

StaticDataTableViewController 2.0

Https://github.com/xelvenone/StaticDataTableViewController

Który może pokazać / ukryć / przeładować dowolną statyczną komórkę(komórki) z animacją lub bez!

[self cell:self.outletToMyStaticCell1 setHidden:hide]; 
[self cell:self.outletToMyStaticCell2 setHidden:hide]; 
[self reloadDataAnimated:YES];

Uwaga, aby zawsze używać tylko (reloadDataAnimated: YES / NO) (dont call [self.tableView reloadData] bezpośrednio)

To nie używa rozwiązania hacky z ustawieniem wysokości na 0 i pozwala na animację zmiany i ukryj całe sekcje

 49
Author: Peter Lapisu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-24 16:23:33

Aby ukryć statyczne komórki w UITable:

  1. Dodaj tę metodę :

W klasie delegata kontrolera UITableView:

Objective-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];
}

Swift:

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)
}

Ta metoda zostanie wywołana dla każdej komórki w UITable. Po wywołaniu komórki, którą chcesz ukryć, ustawiamy jej wysokość na 0. Identyfikujemy komórkę docelową tworząc dla niej ujście:

  1. w Projektancie, stwórz outlet dla komórki, które chcesz ukryć. ujście jednej z takich komórek nazywa się powyżej "cellYouWantToHide".
  2. zaznacz "Podwidywacze klipów" w IB dla komórek, które chcesz ukryć. komórki, które ukrywasz, muszą mieć ClipToBounds = YES. W przeciwnym razie tekst zostanie ułożony w widoku UITableView.
 154
Author: Justas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-16 23:12:16

Najlepszy sposób jest opisany w poniższym blogu http://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/

Zaprojektuj statyczny widok tabeli jako normalny w interfejsie builder – w komplecie ze wszystkimi potencjalnie ukrytymi komórkami. Ale jest jedna rzecz, którą ty musi zrobić dla każdej potencjalnej komórki, którą chcesz ukryć-sprawdź Właściwość "Clip subviews" komórki, w przeciwnym razie zawartość komórka nie znika, gdy próbujesz ją ukryć (zmniejszając ją wysokość - więcej później).

Więc - masz przełącznik w komórce i przełącznik ma się ukrywać i pokazać jakieś statyczne komórki. Podłącz go do IBAction i tam zrób to:

[self.tableView beginUpdates];
[self.tableView endUpdates];

To daje ładne animacje dla pojawiających się komórek i znikają. Teraz zaimplementuj następującą metodę delegata widoku tabeli:

- (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;
}
I to wszystko. Odwróć przełącznik, a komórka ukryje się i pojawi się ponownie z Ładna, płynna animacja.
 35
Author: Mohamed Saleh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-07 19:37:14

Moje rozwiązanie idzie w podobnym kierunku jak Gareth, choć niektóre rzeczy robię inaczej.

Idzie:

1. Ukryj komórki

Nie ma możliwości bezpośredniego ukrycia komórek. {[2] } jest źródłem danych, które dostarcza komórki statyczne i obecnie nie ma sposobu, aby powiedzieć mu "nie dostarczaj komórki x". Musimy więc dostarczyć własne źródło danych, które deleguje do UITableViewController, aby uzyskać komórki statyczne.

Najłatwiej jest podklasować UITableViewController i nadpisać wszystkie metody, które muszą zachowywać się inaczej podczas ukrywania komórek .

W najprostszym przypadku (pojedyncza tabela sekcji, Wszystkie komórki mają tę samą wysokość), wygląda to tak:

- (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];
}

Jeśli tabela ma wiele sekcji lub komórki mają różną wysokość, musisz nadpisać więcej metod. Ta sama zasada obowiązuje tutaj: przed delegowaniem do super musisz przesunąć ścieżkę indexPath, sekcję i wiersz.

Należy również pamiętać, że parametr indexPath dla metod takich jak didSelectRowAtIndexPath: będzie różna dla tej samej komórki, w zależności od stanu (tj. liczby ukrytych komórek). Jest więc prawdopodobnie dobrym pomysłem, aby zawsze kompensować dowolny parametr indexPath i pracować z tymi wartościami.

2. Animacja zmiany

Jak już powiedział Gareth, pojawią się poważne usterki, jeśli animujesz zmiany za pomocą metody reloadSections:withRowAnimation:.

Dowiedziałem się, że jeśli zadzwonisz reloadData: zaraz po tym, animacja jest znacznie ulepszona (pozostały tylko drobne usterki). Tabela jest wyświetlana poprawnie po animacji.

Więc to co robię to:

- (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];
}
 34
Author: henning77,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-13 10:04:31
  1. w Projektancie Utwórz wyjście dla komórki(komórek), które chcesz ukryć. Na przykład chcesz ukryć 'cellOne' , więc w viewDidLoad () zrób to

CellOneOutlet.hidden = true

Teraz nadpisuje poniższą metodę, sprawdź, który stan komórki jest ukryty i zwróć Wysokość 0 dla tych komórek. Jest to jeden z wielu sposobów na ukrycie dowolnej komórki w static tableView w języku swift.

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)
        }

}
 12
Author: Saleh Masum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-04 04:30:26

Wymyśliłem alternatywę, która faktycznie ukrywa sekcje i nie usuwa ich. Próbowałem podejścia @ henning77, ale ciągle miałem problemy, gdy zmieniłem liczbę sekcji statycznego UITableView. Ta metoda działa naprawdę dobrze dla mnie, ale przede wszystkim staram się ukryć sekcje zamiast wierszy. Usuwam kilka wierszy w locie z powodzeniem, ale jest to dużo messier, więc próbowałem pogrupować rzeczy w sekcje, które muszę pokazać lub ukryć. Oto przykład jak jestem ukrywanie sekcji:

Najpierw deklaruję własność NSMutableArray

@property (nonatomic, strong) NSMutableArray *hiddenSections;

W viewDidLoad (lub po zapytaniu danych) możesz dodać sekcje, które chcesz ukryć do tablicy.

- (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];
}

Następnie zaimplementuj następujące metody delegata TableView

- (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];
    }
}

Następnie Ustaw wysokość nagłówka i stopki na 1 dla ukrytych sekcji, ponieważ nie możesz ustawić wysokości na 0. Powoduje to dodatkowe 2 piksele przestrzeni, ale możemy to nadrobić, dostosowując wysokość następnego widoczny nagłówek.

-(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];
}

Następnie, jeśli masz określone wiersze do ukrycia, możesz dostosować numerofrowsinsection i które wiersze są zwracane w cellForRowAtIndexPath. W tym przykładzie mam sekcję, która ma trzy wiersze, w których dowolne trzy mogą być puste i muszą zostać usunięte.

- (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]];
}

Użyj tej offsetIndexPath, aby obliczyć ścieżkę indeksową dla wierszy, w których warunkowo usuwasz wiersze. Nie jest potrzebny, jeśli ukrywasz tylko sekcje

- (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;
}

Istnieje wiele metod, aby override, ale to, co lubię w tym podejściu, to to, że jest wielokrotnego użytku. Ustaw tablicę hiddenSections, Dodaj do niej, a ukryje ona poprawne sekcje. Ukrywanie rzędów jest trochę trudniejsze, ale możliwe. Nie możemy po prostu ustawić wysokości wierszy, które chcemy ukryć, na 0, jeśli używamy pogrupowanego widoku UITableView, ponieważ obramowania nie zostaną narysowane poprawnie.

 11
Author: Austin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-02 18:44:37

Okazuje się, że możesz ukryć i pokazać komórki w statycznym widoku UITableView - iz animacją. I to nie jest takie trudne do osiągnięcia.

Projekt Demo

Demo project video

The gist:

  1. Use tableView:heightForRowAtIndexPath: aby dynamicznie określać wysokość komórek na podstawie pewnego stanu.
  2. gdy stan zmienia wyświetlanie/ukrywanie komórek animate przez wywołanie tableView.beginUpdates();tableView.endUpdates()
  3. nie wywołaj tableView.cellForRowAtIndexPath: wewnątrz tableView:heightForRowAtIndexPath:. Użyj buforowanych ścieżek indeksowych, aby odróżnić komórki.
  4. nie ukrywaj komórek. Zamiast tego ustaw właściwość "Clip Subviews" w Xcode.
  5. Użyj niestandardowych komórek (nie zwykłych itp.), Aby uzyskać przyjemną animację ukrywania. Obsługuje również układ Automatyczny poprawnie Dla Przypadku, Gdy wysokość komórki = = 0.

Więcej informacji na moim blogu (język rosyjski)

 9
Author: Sergey Skoblikov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-25 14:26:26

Tak, to na pewno możliwe, chociaż zmagam się z tym samym problemem w tej chwili. Udało mi się ukryć komórki i wszystko działa ok, ale obecnie nie mogę porządnie animować rzeczy. Oto co znalazłem:

Ukrywam wiersze na podstawie stanu włącznika / wyłącznika w pierwszym rzędzie pierwszej sekcji. Jeśli przełącznik jest włączony, znajduje się pod nim 1 rząd w tej samej sekcji, w przeciwnym razie są 2 różne wiersze.

Mam selektor wywołany, gdy przełącznik jest przełączany i ustawiam zmienną, aby wskazać, w którym stanie jestem. Wtedy wołam:

[[self tableView] reloadData];

Nadpisuję funkcję tableView:willDisplayCell: forRowAtIndexPath: i jeśli komórka ma być ukryta robię to:

[cell setHidden:YES];

Który ukrywa komórkę i jej zawartość, ale nie usuwa zajmowanego przez nią miejsca.

Aby usunąć spację, Nadpisz funkcję tableView:heightForRowAtIndexPath: i zwróć 0 dla wierszy, które powinny być ukryte.

Musisz także nadpisać tableView:numerofrowsinsection: i zwrócić liczbę wierszy w tej sekcji. Musisz zrobić tutaj coś dziwnego, aby jeśli twoja tabela jest stylem zgrupowanym, zaokrąglone rogi występują na właściwych komórkach. W mojej tabeli statycznej znajduje się pełny zestaw komórek dla sekcji, więc jest pierwsza komórka zawierająca opcję, następnie 1 Komórka dla opcji stanu ON i 2 więcej komórek dla opcji stanu OFF, w sumie 4 komórki. Gdy opcja jest włączona, I musisz zwrócić 4, obejmuje To opcję ukrytą, aby ostatnia wyświetlona opcja miała zaokrąglone pole. Gdy opcja jest wyłączona, dwie ostatnie opcje nie są wyświetlane, więc zwracam 2. To wszystko wydaje się niezgrabne. Przepraszam, jeśli to nie jest zbyt jasne, to trudne do opisania. Aby zilustrować konfigurację, jest to konstrukcja sekcji tabeli w IB:

  • wiersz 0: opcja z włącznikiem / wyłącznikiem
  • wiersz 1: wyświetlany, gdy opcja jest włączona
  • wiersz 2: wyświetlany, gdy opcja jest OFF
  • wiersz 3: wyświetlany, gdy opcja jest wyłączona

Więc gdy opcja znajduje się w tabeli zgłasza dwa wiersze, które są:

  • wiersz 0: opcja z włącznikiem / wyłącznikiem
  • wiersz 1: wyświetlany, gdy opcja jest włączona

Gdy opcja jest poza tabelą zgłasza cztery wiersze, które są:

  • wiersz 0: opcja z włącznikiem / wyłącznikiem
  • wiersz 1: wyświetlany, gdy opcja jest włączona
  • wiersz 2: wyświetlany, gdy opcja jest wyłączona
  • wiersz 3: wyświetlany, gdy opcja jest wyłączona

To podejście nie wydaje się poprawne z kilku powodów, to tak daleko, jak mam z moich eksperymentów do tej pory, więc proszę dać mi znać, jeśli znajdziesz lepszy sposób. Problemy jakie dotychczas zaobserwowałem to:

  • Źle jest mówić tabeli, że liczba wierszy różni się od tego, co prawdopodobnie zawiera podstawowe dane.

  • Nie mogę ożywić zmiany. Próbowałem użyć tableView: reloadSections: withRowAnimation: zamiast reloadData i wyniki nie wydają się mieć sensu, nadal próbuję to uruchomić. Obecnie wydaje się, że tableView nie aktualizuje poprawnych wierszy, więc pozostaje ukryty, który powinien być wyświetlony, a pustka pozostaje pod pierwszym wierszem. Myślę, że może to być związane z pierwszym punktem dotyczącym podstawowych danych.

Mam nadzieję, że ktoś będzie w stanie zaproponować alternatywne metody, a może jak rozszerzyć z animacją, ale może to pomoże Ci zacząć. Przepraszam za brak hiperłączy do funkcji, wstawiłem je, ale zostały odrzucone przez filtr antyspamowy, ponieważ jestem dość nowym użytkownikiem.

 8
Author: Gareth Clarke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-29 11:04:35

Powyższe odpowiedzi, które ukrywają / pokazują komórki, zmieniają rowHeight lub bałagan z ograniczeniami układu automatycznego, nie działały dla mnie z powodu problemów z układem automatycznym. Kodeks stał się nie do przyjęcia.

Dla prostej statycznej tabeli, to, co działało dla mnie najlepiej, to:

  1. Tworzenie wylotu dla każdej komórki w tabeli statycznej
  2. tworzenie tablicy tylko z wylotami komórek do pokazania
  3. Override cellForRowAtIndexPath zwraca komórkę z tablicy
  4. Override numerofrowsinsection Zwraca liczbę tablicy
  5. zaimplementuj metodę, która określi, jakie komórki muszą znajdować się w tej tablicy, i wywołaj tę metodę w razie potrzeby, a następnie przeładujdata.

Oto przykład z mojego kontrolera widoku tabeli:

@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
}
 3
Author: David Barta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-13 06:03:12

Zgodnie z odpowiedzią Justasa, ale dla 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)
}
 2
Author: Chris Herbst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-17 08:14:20

Znalazłem rozwiązanie do ukrywania komórek programu animate w tabeli statycznej.

// 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

Potrzebny tylko jeden dodatkowy słownik:

@interface MyTableViewController ()
@property (nonatomic) NSMutableDictionary * hidableCellsDict;
@property (weak, nonatomic) IBOutlet UISwitch * birthdaySwitch;
@end

I spójrz na implementację MyTableViewController. Potrzebujemy dwóch metod konwersji ścieżki indeksowej pomiędzy indeksami widzialnymi i niewidocznymi...

- (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];
}

Jedna akcja przy zmianie wartości Uiswitcha:

- (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];
}

Niektóre metody UITableViewDataSource i 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
 1
Author: k06a,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-22 09:47:30

Odpowiedź w :

Dodaj następującą metodę do TableViewController:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return indexPathOfCellYouWantToHide == indexPath ? 0 : super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}

Jeśli tableView spróbuje narysować komórkę, którą chcesz ukryć, to nie wyświetli jej, ponieważ jej wysokość zostanie ustawiona na 0pt dzięki powyższej metodzie, Wszystko inne pozostanie niezmienione.

Należy pamiętać, że indexPathOfCellYouWantToHide można zmienić w dowolnym momencie:)

 1
Author: Federico Zanetello,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 15:11:26

W > Swift 2.2, połączyłem kilka odpowiedzi tutaj.

Zrób ujście ze storyboardu, aby połączyć się ze staticCell.

@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)
    }
}

Chcę ukryć moją pierwszą komórkę, więc ustawiłem wysokość na 0, jak opisano powyżej.

 1
Author: CodeOverRide,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-14 00:06:29

Prosta metoda kompatybilna z iOS 11 i IB/Storyboard

Dla iOS 11 okazało się, że zmodyfikowana wersja Odpowiedzi Mohameda Saleha działa najlepiej, z pewnymi ulepszeniami w oparciu o dokumentację Apple. Ładnie animuje, unika brzydkich hacków lub zakodowanych na twardo wartości, a używa wysokości wierszy już ustawionych w Interface Builder.

Podstawową koncepcją jest ustawienie wysokości wiersza na 0 dla dowolnych ukrytych wierszy. Następnie użyj tableView.performBatchUpdates aby uruchomić animację, która działa konsekwentnie.

Ustaw wysokość komórek

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)
}

Upewnij się, że cellIsHidden i indexPathOfHiddenCell są ustawione odpowiednio do twojego przypadku użycia. Dla mojego kodu są to właściwości na kontrolerze widoku tabeli.

Przełączanie komórki

W zależności od tego, która metoda kontroluje widoczność (prawdopodobnie działanie przycisku lub didSelectRow), przełącza stan cellIsHidden wewnątrz bloku performBatchUpdates:
tableView.performBatchUpdates({
                // Use self to capture for block
                self.cellIsHidden = !self.cellIsHidden 
            }, completion: nil)

Apple poleca performBatchUpdates over beginUpdates/endUpdates o ile to możliwe.

 1
Author: robmathers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-26 21:31:46

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
}
 1
Author: pizzamonster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-26 13:03:47

Dla najprostszego scenariusza, gdy ukrywasz komórki na samym dole widoku tabeli, możesz dostosować contentInset tableView po ukryciu komórki:

- (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);
}
 0
Author: Vladimir Shutyuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-25 12:00:45

To jest nowy sposób, aby to zrobić za pomocą https://github.com/k06a/ABStaticTableViewController

NSIndexPath *ip = [NSIndexPath indexPathForRow:1 section:1];
[self deleteRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationFade]
 0
Author: k06a,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-06 10:00:27

Roztwór z k06a ( https://github.com/k06a/ABStaticTableViewController ) jest lepszy, ponieważ ukrywa całą sekcję, w tym nagłówki komórek i stopki, gdzie to rozwiązanie ( https://github.com/peterpaulis/StaticDataTableViewController ) ukrywa wszystko oprócz stopki.

Edytuj

Właśnie znalazłem rozwiązanie, jeśli chcesz ukryć stopkę w StaticDataTableViewController. To jest to, co musisz skopiować w StaticTableViewController.plik 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;
}
 0
Author: pawel221,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-31 12:51:05

Z pewnością możesz. Najpierw wróć do tableView liczba komórek, które chcesz wyświetlić, a następnie zadzwoń super, aby uzyskać określoną komórkę z storyboardu i zwróć ją dla 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
}

Jeśli twoje komórki mają inny kolor, zwróć też:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return super.tableView(tableView, heightForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))
}
 0
Author: Petr Syrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-08 13:15:54

Oprócz @Saleh Masum solution:

Jeśli pojawią się błędy automatycznego układu , możesz po prostu usunąć ograniczenia z tableViewCell.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)
    }

}

To rozwiązanie zależy od przepływu aplikacji . Jeśli chcesz pokazać/ukryć komórkę w tej samej instancji kontrolera widoku, może to nie być najlepszy wybór, ponieważ usuwa ograniczenia .

 0
Author: Luca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-22 14:24:59