Espandi/comprimi sezione UITableView in iOS

Qualcuno potrebbe dirmi il modo per eseguire UITableView espandibile/comprimibile animazioni in sections di UITableView come di seguito?

Espandi/comprimi sezione UITableView in iOS

o

Espandi/comprimi sezione UITableView in iOS

InformationsquelleAutor vinnitu | 2009-12-21



17 Replies
  1. 107

    Devi fare personalizzati riga di intestazione e metti come prima riga di ogni sezione. La creazione di sottoclassi della UITableView o intestazioni che sono già lì sarà un dolore. In base al modo di lavorare ora, io non sono sicuro che si può facilmente ottenere azioni di fuori di essi. Si può impostare una cella a GUARDARE come una intestazione, l’installazione e la tableView:didSelectRowAtIndexPath manualmente espandere o comprimere la sezione è in.

    Vorrei memorizzare un array di booleani corrispondente la “spesa” del valore di ciascuna delle sezioni. Quindi si potrebbe avere il tableView:didSelectRowAtIndexPath su ogni intestazione personalizzata righe passare questo valore e quindi ricaricare una sezione specifica.

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        if (indexPath.row == 0) {
            ///it's the first row of any section so it would be your custom section header
    
            ///put in your code to toggle your boolean value here
            mybooleans[indexPath.section] = !mybooleans[indexPath.section];
    
            ///reload this section
            [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
        }
    }

    Quindi impostare numberOfRowsInSection per verificare il mybooleans valore e restituisce 1 se la sezione non è espansa o 1+ il numero di elementi nella sezione se si è espansa.

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
        if (mybooleans[section]) {
            ///we want the number of people plus the header cell
            return [self numberOfPeopleInGroup:section] + 1;
        } else {
            ///we just want the header cell
            return 1;
        }
    }

    Inoltre, è necessario aggiornare cellForRowAtIndexPath per il ritorno di una intestazione personalizzata cella per la prima riga di ogni sezione.

    • se hai usato il Beejive app, si dovrebbe sapere che la loro pieghevole sezione di intestazione in realtà “galleggiare” nella parte superiore della tabella, anche quando ti sei spostato attraverso una parte della sua sezione, proprio come il normale Apple intestazioni di sezione. non è possibile, se è sufficiente aggiungere una cella all’inizio della sezione
    • Bella soluzione elegante! user102008 ha un punto sul flottante di intestazione, ma in uno scenario in cui si desidera che in realtà il “sezioni” di scorrimento, questo è un ottimo approccio.
    • plz datemi qualche codice di esempio bcz ho bisogno di una specifica cella di nascondere/mostrare ..grazie in anticipo
    • - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section è il modo migliore per fornire loro intestazione personalizzata”, che è esattamente quello per cui è stato progettato.
    • questo inizialmente ha lavorato per me quando ho avuto solo una sezione, ma appena ho avuto di più, ho l’ “aggiornamento non valido non valido numero di righe di errore”. so che questa soluzione è più vecchio, ma questo solo per una sezione? se abbiamo più di una sezione, avremo bisogno di aggiungere il codice che in realtà aggiunge/elimina le righe??
    • Questo può essere una buona soluzione in passato, ma ora è sicuramente meglio, semplicemente, sottoclasse UITableViewHeaderFooterView e tenere traccia dei dati con gli indici.

  2. 103

    Qualche esempio di codice per l’animazione di un’azione espandi/comprimi utilizzando una tabella in visualizzazione intestazione di sezione è fornito da Apple qui: Tabella di Visualizzazione delle Animazioni e dei Gesti

    La chiave di questo approccio è quello di implementare - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section e di ritorno personalizzato UIView che include un pulsante (in genere la stessa dimensione come l’intestazione di vista). Sottoclasse di UIView e l’utilizzo che per la visualizzazione dell’intestazione (come in questo esempio), si può facilmente memorizzare altri dati come il numero della sezione.

    • Fantastico, grazie: developer.apple.com/library/ios/#samplecode/TableViewUpdates/…
    • c’è un esempio di codice che funziona sulla pre-iOS 4?
    • non ricordo, ma perché è l’esempio di codice che non funziona sul pre-iOS 4?
    • non so. si dice solo che “iOS 4.0.2 o poi”
    • probabilmente non funzionerà pre iOS 4, perché è per mezzo dell’ARCO e altre tecnologie.
    • L’attuale codice aggiornato il link ha bug in esso e può essere arrestato facilmente
    • Si sono ancora in cura per iOS 4 !!!
    • Come Condor Srivastava accennato prima, è facile rompere questo codice di esempio: basta copiare e incollare tutti gli elementi dizionari del PlaysAndQuotations.plist (l’ho provato con 30 voci nella root del dizionario) – Ora avviare l’app e aprire il primo play – dopo di che si scorrere verso il basso fino a visualizzare una freccia rivolta verso il basso (credo che questo viene da dequeueReusableHeaderFooterViewWithIdentifier) clic sulla freccia e selezionare il primo gioco e cercare di chiuderla -> NSInternalInconsistencyException (iOS 8.4 / 5s iPhone)

  3. 22

    Ho avuto una bella soluzione ispirata da Apple Tabella di Visualizzazione delle Animazioni e dei Gesti. Ho eliminato le parti inutili da Apple campione e tradotto in swift.

    So che la risposta è abbastanza lungo, ma tutto il codice necessario. Fortunatamente, è possibile copiare semplicemente&passato la maggior parte del codice e solo bisogno di fare un po ‘ di modifiche sul punto 1 e 3,

    1.creare SectionHeaderView.swift e SectionHeaderView.xib

    import UIKit
    
    protocol SectionHeaderViewDelegate {
        func sectionHeaderView(sectionHeaderView: SectionHeaderView, sectionOpened: Int)
        func sectionHeaderView(sectionHeaderView: SectionHeaderView, sectionClosed: Int)
    }
    
    class SectionHeaderView: UITableViewHeaderFooterView {
    
        var section: Int?
        @IBOutlet weak var titleLabel: UILabel!
        @IBOutlet weak var disclosureButton: UIButton!
        @IBAction func toggleOpen() {
            self.toggleOpenWithUserAction(true)
        }
        var delegate: SectionHeaderViewDelegate?
    
        func toggleOpenWithUserAction(userAction: Bool) {
            self.disclosureButton.selected = !self.disclosureButton.selected
    
            if userAction {
                if self.disclosureButton.selected {
                    self.delegate?.sectionHeaderView(self, sectionClosed: self.section!)
                } else {
                    self.delegate?.sectionHeaderView(self, sectionOpened: self.section!)
                }
            }
        }
    
        override func awakeFromNib() {
            var tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "toggleOpen")
            self.addGestureRecognizer(tapGesture)
            //change the button image here, you can also set image via IB.
            self.disclosureButton.setImage(UIImage(named: "arrow_up"), forState: UIControlState.Selected)
            self.disclosureButton.setImage(UIImage(named: "arrow_down"), forState: UIControlState.Normal)
        }
    
    }

    il SectionHeaderView.xib(la vista con sfondo grigio) dovrebbe essere qualcosa di simile a questo in una tableview(è possibile personalizzare in base alle vostre esigenze, ovviamente):
    Espandi/comprimi sezione UITableView in iOS

    nota:

    a) il toggleOpen azione dovrebbe essere collegato alla disclosureButton

    b) il disclosureButton e toggleOpen azione non sono necessari. È possibile eliminare queste 2 cose, se non avete bisogno di un pulsante.

    2.creare SectionInfo.swift

    import UIKit
    
    class SectionInfo: NSObject {
        var open: Bool = true
        var itemsInSection: NSMutableArray = []
        var sectionTitle: String?
    
        init(itemsInSection: NSMutableArray, sectionTitle: String) {
            self.itemsInSection = itemsInSection
            self.sectionTitle = sectionTitle
        }
    }

    3.nel tableview

    import UIKit
    
    class TableViewController: UITableViewController, SectionHeaderViewDelegate  {
    
        let SectionHeaderViewIdentifier = "SectionHeaderViewIdentifier"
    
        var sectionInfoArray: NSMutableArray = []
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let sectionHeaderNib: UINib = UINib(nibName: "SectionHeaderView", bundle: nil)
            self.tableView.registerNib(sectionHeaderNib, forHeaderFooterViewReuseIdentifier: SectionHeaderViewIdentifier)
    
            //you can change section height based on your needs
            self.tableView.sectionHeaderHeight = 30
    
            //You should set up your SectionInfo here
            var firstSection: SectionInfo = SectionInfo(itemsInSection: ["1"], sectionTitle: "firstSection")
            var secondSection: SectionInfo = SectionInfo(itemsInSection: ["2"], sectionTitle: "secondSection"))
            sectionInfoArray.addObjectsFromArray([firstSection, secondSection])
        }
    
        //MARK: - Table view data source
    
        override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
            return sectionInfoArray.count
        }
    
        override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if self.sectionInfoArray.count > 0 {
                var sectionInfo: SectionInfo = sectionInfoArray[section] as! SectionInfo
                if sectionInfo.open {
                    return sectionInfo.open ? sectionInfo.itemsInSection.count : 0
                }
            }
            return 0
        }
    
        override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            let sectionHeaderView: SectionHeaderView! = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier(SectionHeaderViewIdentifier) as! SectionHeaderView
            var sectionInfo: SectionInfo = sectionInfoArray[section] as! SectionInfo
    
            sectionHeaderView.titleLabel.text = sectionInfo.sectionTitle
            sectionHeaderView.section = section
            sectionHeaderView.delegate = self
            let backGroundView = UIView()
            //you can customize the background color of the header here
            backGroundView.backgroundColor = UIColor(red:0.89, green:0.89, blue:0.89, alpha:1)
            sectionHeaderView.backgroundView = backGroundView
            return sectionHeaderView
        }
    
        func sectionHeaderView(sectionHeaderView: SectionHeaderView, sectionOpened: Int) {
            var sectionInfo: SectionInfo = sectionInfoArray[sectionOpened] as! SectionInfo
            var countOfRowsToInsert = sectionInfo.itemsInSection.count
            sectionInfo.open = true
    
            var indexPathToInsert: NSMutableArray = NSMutableArray()
            for i in 0..<countOfRowsToInsert {
                indexPathToInsert.addObject(NSIndexPath(forRow: i, inSection: sectionOpened))
            }
            self.tableView.insertRowsAtIndexPaths(indexPathToInsert as [AnyObject], withRowAnimation: .Top)
        }
    
        func sectionHeaderView(sectionHeaderView: SectionHeaderView, sectionClosed: Int) {
            var sectionInfo: SectionInfo = sectionInfoArray[sectionClosed] as! SectionInfo
            var countOfRowsToDelete = sectionInfo.itemsInSection.count
            sectionInfo.open = false
            if countOfRowsToDelete > 0 {
                var indexPathToDelete: NSMutableArray = NSMutableArray()
                for i in 0..<countOfRowsToDelete {
                    indexPathToDelete.addObject(NSIndexPath(forRow: i, inSection: sectionClosed))
                }
                self.tableView.deleteRowsAtIndexPaths(indexPathToDelete as [AnyObject], withRowAnimation: .Top)
            }
        }
    }
    • grazie per lo sforzo su questo! Con un piccolo progetto di esempio su github sarebbe ancora migliori risposte
    • Grazie per la fornitura di dettaglio di risposta.Il progetto di esempio sarebbe meglio.
  4. 14

    Per implementare il tavolo ribaltabile sezione iOS, la magia è come controllare il numero di righe per ogni sezione, o siamo in grado di gestire l’altezza delle righe per ogni sezione.

    Inoltre, abbiamo bisogno di personalizzare l’intestazione della sezione in modo che possiamo ascoltare il rubinetto evento dall’area di intestazione (se si tratta di un pulsante o l’intera intestazione).

    Come trattare con l’intestazione? E ‘ molto semplice, possiamo estendere la UITableViewCell di classe e di fare un custom cella di intestazione in questo modo:

    import UIKit
    
    class CollapsibleTableViewHeader: UITableViewCell {
    
        @IBOutlet var titleLabel: UILabel!
        @IBOutlet var toggleButton: UIButton!
    
    }

    quindi utilizzare il viewForHeaderInSection agganciare la cella di intestazione:

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
      let header = tableView.dequeueReusableCellWithIdentifier("header") as! CollapsibleTableViewHeader
    
      header.titleLabel.text = sections[section].name
      header.toggleButton.tag = section
      header.toggleButton.addTarget(self, action: #selector(CollapsibleTableViewController.toggleCollapse), forControlEvents: .TouchUpInside)
    
      header.toggleButton.rotate(sections[section].collapsed! ? 0.0 : CGFloat(M_PI_2))
    
      return header.contentView
    }

    ricordo che abbiamo per restituire il contentView perché la funzione si aspetta una UIView essere restituiti.

    Ora facciamo accordo con il pieghevole parte, qui è la funzione toggle che alterna il pieghevole elica di ogni sezione:

    func toggleCollapse(sender: UIButton) {
      let section = sender.tag
      let collapsed = sections[section].collapsed
    
      //Toggle collapse
      sections[section].collapsed = !collapsed
    
      //Reload section
      tableView.reloadSections(NSIndexSet(index: section), withRowAnimation: .Automatic)
    }

    dipende da come si gestisce la sezione di dati, in questo caso, ho la sezione dati qualcosa di simile a questo:

    struct Section {
      var name: String!
      var items: [String]!
      var collapsed: Bool!
    
      init(name: String, items: [String]) {
        self.name = name
        self.items = items
        self.collapsed = false
      }
    }
    
    var sections = [Section]()
    
    sections = [
      Section(name: "Mac", items: ["MacBook", "MacBook Air", "MacBook Pro", "iMac", "Mac Pro", "Mac mini", "Accessories", "OS X El Capitan"]),
      Section(name: "iPad", items: ["iPad Pro", "iPad Air 2", "iPad mini 4", "Accessories"]),
      Section(name: "iPhone", items: ["iPhone 6s", "iPhone 6", "iPhone SE", "Accessories"])
    ]

    all’ultimo, quello che dobbiamo fare è basato sul pieghevole elica di ogni sezione, di controllare il numero di righe della sezione:

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return (sections[section].collapsed!) ? 0 : sections[section].items.count
    }

    Ho una demo completamente funzionante sul mio Github: https://github.com/jeantimex/ios-swift-collapsible-table-section

    Espandi/comprimi sezione UITableView in iOS

    Se si desidera implementare le sezioni comprimibili in un raggruppati in stile tavolo, ho un’altra demo con il codice sorgente qui: https://github.com/jeantimex/ios-swift-collapsible-table-section-in-grouped-section

    Speranza che aiuta.

    • Ciao, ho fatto la mia custom sezione di intestazione di un file xib e registrato il pennino per il mio Table View Controller. Quando si elimina una sezione e cercare di espandere/comprimere di nuovo, ho un fatale errore che dice che l’indice è fuori portata. C’è qualche modo per risolvere questo problema? Grazie!
    • molto bella e pulita la soluzione!
  5. 10

    Ho una soluzione migliore che si dovrebbe aggiungere un UIButton nella sezione di intestazione e impostare il pulsante di dimensione pari alla sezione di misura, ma nascosto dal chiaro colore di sfondo, dopo che si sono facilmente verificare che la sezione è fatto clic per espandere o comprimere

    • A mio parere, questa soluzione è migliore rispetto accettato la risposta, in quanto semanticamente a mantenere la vostra intestazione intestazione e non si utilizza un falso fila per simulare un colpo di testa. Metodo tableView:numberOfRowsInSection: resterà intatto e si continuerà a essere in grado di usarlo per quello che realmente significa. Lo stesso vale per tableView:cellForRowAtIndexPath:.
    • Così, si tocca il pulsante nella sezione di intestazione, ma come hai intenzione di determinare quale sezione deve essere ricaricato?
    • Ciao, è estremamente facile da impostazione tag pulsante con lo stesso valore con indice di sezione.
    • Aveva paura, si direbbe che. L’abuso della proprietà tag per cose come tableView indici di una scarsa scelta di design.
    • avete qualche soluzione migliore? pls vedi qui.
    • Non ho mai visto nessun “grande” soluzioni al problema, che è il motivo per cui speravo che aveva un approccio diverso. La risposta migliore che ho visto è la Apple progetto di riferimento. Apple sottoclassi di UITableViewHeaderFooterView e aggiunge un section proprietà e definisce un SectionHeaderViewDelegate che fornisce la funzione di callback per aprire/chiudere la sezione. (developer.apple.com/library/ios/samplecode/TableViewUpdates/…)

  6. 6

    Ho finito solo la creazione di un headerView che conteneva un pulsante ( ho visto Figlio Nguyen soluzione sopra, dopo il fatto, ma heres il mio codice.. sembra come un sacco, ma è abbastanza semplice):

    dichiarare un paio bools per voi sezioni

    bool customerIsCollapsed = NO;
    bool siteIsCollapsed = NO;

    …codice

    ora nel tuo tableview delegato metodi…

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _tblSearchResults.frame.size.width, 35)];
    
        UILabel *lblSection = [UILabel new];
        [lblSection setFrame:CGRectMake(0, 0, 300, 30)];
        [lblSection setFont:[UIFont fontWithName:@"Helvetica-Bold" size:17]];
        [lblSection setBackgroundColor:[UIColor clearColor]];
        lblSection.alpha = 0.5;
        if(section == 0)
        {
            if(!customerIsCollapsed)
                [lblSection setText:@"Customers    --touch to show--"];
            else
                [lblSection setText:@"Customers    --touch to hide--"];
        }
        else
        {
            if(!siteIsCollapsed)
                [lblSection setText:@"Sites    --touch to show--"];
            else
                [lblSection setText:@"Sites    --touch to hide--"];    }
    
        UIButton *btnCollapse = [UIButton buttonWithType:UIButtonTypeCustom];
        [btnCollapse setFrame:CGRectMake(0, 0, _tblSearchResults.frame.size.width, 35)];
        [btnCollapse setBackgroundColor:[UIColor clearColor]];
        [btnCollapse addTarget:self action:@selector(touchedSection:) forControlEvents:UIControlEventTouchUpInside];
        btnCollapse.tag = section;
    
    
        [headerView addSubview:lblSection];
        [headerView addSubview:btnCollapse];
    
        return headerView;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        //Return the number of rows in the section.
        if(section == 0)
        {
            if(customerIsCollapsed)
                return 0;
            else
                return _customerArray.count;
        }
        else if (section == 1)
        {
            if(siteIsCollapsed)
                return 0;
            else
            return _siteArray.count;
    
        }
        return 0;
    }

    e, infine, la funzione che viene chiamata quando si tocca uno dei intestazione di sezione pulsanti:

    - (IBAction)touchedSection:(id)sender
    {
        UIButton *btnSection = (UIButton *)sender;
    
        if(btnSection.tag == 0)
        {
            NSLog(@"Touched Customers header");
            if(!customerIsCollapsed)
                customerIsCollapsed = YES;
            else
                customerIsCollapsed = NO;
    
        }
        else if(btnSection.tag == 1)
        {
            NSLog(@"Touched Site header");
            if(!siteIsCollapsed)
                siteIsCollapsed = YES;
            else
                siteIsCollapsed = NO;
    
        }
        [_tblSearchResults reloadData];
    }
    • Mi stavo chiedendo, se la sezione di comprimere ed espandere animati o senza animazione. Senza animazione sarà un aspetto molto male. come possiamo aggiungere animazione ?
    • se si utilizza qualcosa come [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade]; nel crollo/uncollapse metodo dovrebbe animare bene.
  7. 5

    Questo è il modo migliore che ho trovato per creare espandibile vista tabella cellule

    .h file

      NSMutableIndexSet *expandedSections;

    .m file

    if (!expandedSections)
        {
            expandedSections = [[NSMutableIndexSet alloc] init];
        }
       UITableView *masterTable = [[UITableView alloc] initWithFrame:CGRectMake(0,100,1024,648) style:UITableViewStyleGrouped];
        masterTable.delegate = self;
        masterTable.dataSource = self;
        [self.view addSubview:masterTable];

    Vista tabella delegato metodi

    - (BOOL)tableView:(UITableView *)tableView canCollapseSection:(NSInteger)section
    {
        //if (section>0) return YES;
    
        return YES;
    }
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        //Return the number of sections.
        return 4;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        if ([self tableView:tableView canCollapseSection:section])
        {
            if ([expandedSections containsIndex:section])
            {
                return 5; //return rows when expanded
            }
    
            return 1; //only top row showing
        }
    
        //Return the number of rows in the section.
        return 1;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
        }
    
        //Configure the cell...
    
        if ([self tableView:tableView canCollapseSection:indexPath.section])
        {
            if (!indexPath.row)
            {
                //first row
                cell.textLabel.text = @"Expandable"; //only top row showing
    
                if ([expandedSections containsIndex:indexPath.section])
                {
    
                    UIImageView *imView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UITableContract"]];
                    cell.accessoryView = imView;
                }
                else
                {
    
                    UIImageView *imView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UITableExpand"]];
                    cell.accessoryView = imView;
                }
            }
            else
            {
                //all other rows
                if (indexPath.section == 0) {
                    cell.textLabel.text = @"section one";
                }else if (indexPath.section == 1) {
                    cell.textLabel.text = @"section 2";
                }else if (indexPath.section == 2) {
                    cell.textLabel.text = @"3";
                }else {
                    cell.textLabel.text = @"some other sections";
                }
    
                cell.accessoryView = nil;
                cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
            }
        }
        else
        {
            cell.accessoryView = nil;
            cell.textLabel.text = @"Normal Cell";
    
        }
    
        return cell;
    }
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if ([self tableView:tableView canCollapseSection:indexPath.section])
        {
            if (!indexPath.row)
            {
                //only first row toggles exapand/collapse
                [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
                NSInteger section = indexPath.section;
                BOOL currentlyExpanded = [expandedSections containsIndex:section];
                NSInteger rows;
    
    
                NSMutableArray *tmpArray = [NSMutableArray array];
    
                if (currentlyExpanded)
                {
                    rows = [self tableView:tableView numberOfRowsInSection:section];
                    [expandedSections removeIndex:section];
    
                }
                else
                {
                    [expandedSections addIndex:section];
                    rows = [self tableView:tableView numberOfRowsInSection:section];
                }
    
    
                for (int i=1; i<rows; i++)
                {
                    NSIndexPath *tmpIndexPath = [NSIndexPath indexPathForRow:i 
                                                                   inSection:section];
                    [tmpArray addObject:tmpIndexPath];
                }
    
                UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    
                if (currentlyExpanded)
                {
                    [tableView deleteRowsAtIndexPaths:tmpArray 
                                     withRowAnimation:UITableViewRowAnimationTop];
    
                    UIImageView *imView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UITableExpand"]];
                    cell.accessoryView = imView;
                }
                else
                {
                    [tableView insertRowsAtIndexPaths:tmpArray 
                                     withRowAnimation:UITableViewRowAnimationTop];
    
                    UIImageView *imView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UITableContract"]];
                    cell.accessoryView = imView;
                }
            }
        }
    
        NSLog(@"section :%d,row:%d",indexPath.section,indexPath.row);
    
    }
    • Probabilmente si dovrebbe bandiera domande come duplicati esatti invece di spamming la stessa risposta su tutti loro.
    • se una sezione è già espansa, e un’altra sezione è cliccato, dà errore
    • ciao sir,l’indice Selezionato altezza come cambiare?heightForRowAtIndexPath come lavorare con il tuo codice?
    • ciao sir come passare a un altro controller di visualizzazione su didselected espanso di fila?
  8. 1

    Così, basato sul pulsante di intestazione’ soluzione, qui è un ambiente pulito e minimalista di attuazione:

    • consente di tenere traccia dei crollato (o espanso) sezioni in una proprietà
    • tag il tasto con l’indice di sezione
    • si imposta stato selezionato il pulsante per cambiare la direzione della freccia (come △ e ▽)

    Ecco il codice:

    @interface MyTableViewController ()
    @property (nonatomic, strong) NSMutableIndexSet *collapsedSections;
    @end
    
    ...
    
    @implementation MyTableViewController
    
    - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (!self)
            return;
        self.collapsedSections = [NSMutableIndexSet indexSet];
        return self;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        //if section is collapsed
        if ([self.collapsedSections containsIndex:section])
            return 0;
    
        //if section is expanded
    #warning incomplete implementation
        return [super tableView:tableView numberOfRowsInSection:section];
    }
    
    - (IBAction)toggleSectionHeader:(UIView *)sender
    {
        UITableView *tableView = self.tableView;
        NSInteger section = sender.tag;
    
        MyTableViewHeaderFooterView *headerView = (MyTableViewHeaderFooterView *)[self tableView:tableView viewForHeaderInSection:section];
    
        if ([self.collapsedSections containsIndex:section])
        {
            //section is collapsed
            headerView.button.selected = YES;
            [self.collapsedSections removeIndex:section];
        }
        else
        {
            //section is expanded
            headerView.button.selected = NO;
            [self.collapsedSections addIndex:section];
        }
    
        [tableView beginUpdates];
        [tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationAutomatic];
        [tableView endUpdates];
    }
    
    @end
  9. 1

    Ho trovato un altro modo relativamente semplice per risolvere il problema. Utilizzando questo metodo da noi non verrà richiesto di modificare la nostra cella, che è quasi sempre legata alla matrice di dati di indice, potenzialmente causando confusione nella nostra view controller.

    Primo, aggiungiamo le seguenti proprietà per il nostro controller classe:

    @property (strong, nonatomic) NSMutableArray* collapsedSections;
    @property (strong, nonatomic) NSMutableArray* sectionViews;

    collapsedSections salverà crollato numeri di sezione.
    sectionViews memorizzare la nostra sezione personalizzata vista.

    Sintetizzare:

    @synthesize collapsedSections;
    @synthesize sectionViews;

    Inizializzazione:

    - (void) viewDidLoad
    {
        [super viewDidLoad];
    
        self.collapsedSections = [NSMutableArray array];
        self.sectionViews      = [NSMutableArray array];
    }

    Dopo di che, dobbiamo collegare il nostro UITableView modo che sia possibile accedervi dall’interno la nostra view controller classe:

    @property (strong, nonatomic) IBOutlet UITableView *tblMain;

    Collegamento da XIB per visualizzare il controller utilizza ctrl + drag come al solito.

    Quindi si crea una vista personalizzata sezione di intestazione per la nostra vista tabella mediante l’attuazione di questa UITableView delegato:

    - (UIView*) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        //Create View
        CGRect frame = CGRectZero;
    
        frame.origin = CGPointZero;
    
        frame.size.height = 30.f;
        frame.size.width  = tableView.bounds.size.width;
    
        UIView* view = [[UIView alloc] initWithFrame:frame];
    
        [view setBackgroundColor:[UIColor blueColor]];
    
        //Add label for title
        NSArray* titles = @[@"Title 1", @"Title 2", @"Title 3"];
    
        NSString* selectedTitle = [titles objectAtIndex:section];
    
        CGRect labelFrame = frame;
    
        labelFrame.size.height = 30.f;
        labelFrame.size.width -= 20.f;
        labelFrame.origin.x += 10.f;
    
        UILabel* titleLabel = [[UILabel alloc] initWithFrame:labelFrame];
    
        [titleLabel setText:selectedTitle];
        [titleLabel setTextColor:[UIColor whiteColor]];
    
        [view addSubview:titleLabel];
    
        //Add touch gesture
        [self attachTapGestureToView:view];
    
        //Save created view to our class property array
        [self saveSectionView:view inSection:section];
    
        return view;
    }

    A quel punto, si implementa il metodo per salvare i nostri personalizzata creata in precedenza intestazione della sezione in classe immobile:

    - (void) saveSectionView:(UIView*) view inSection:(NSInteger) section
    {
        NSInteger sectionCount = [self numberOfSectionsInTableView:[self tblMain]];
    
        if(section < sectionCount)
        {
            if([[self sectionViews] indexOfObject:view] == NSNotFound)
            {
                [[self sectionViews] addObject:view];
            }
        }
    }

    Aggiungere UIGestureRecognizerDelegate per la nostra view controller .h:

    @interface MyViewController : UIViewController<UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate>

    Quindi per creare metodo attachTapGestureToView:

    - (void) attachTapGestureToView:(UIView*) view
    {
        UITapGestureRecognizer* tapAction = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
    
        [tapAction setDelegate:self];
    
        [view addGestureRecognizer:tapAction];
    }

    Metodo di cui sopra potranno aggiungere tocco gesto di riconoscimento a tutti di vista di sezione che abbiamo creato prima. Poi si dovrebbero implementare onTap: selettore

    - (void) onTap:(UITapGestureRecognizer*) gestureRecognizer
    {
        //Take view who attach current recognizer
        UIView* sectionView = [gestureRecognizer view]; 
    
        //[self sectionViews] is Array containing our custom section views
        NSInteger section = [self sectionNumberOfView:sectionView];
    
        //[self tblMain] is our connected IBOutlet table view
        NSInteger sectionCount = [self numberOfSectionsInTableView:[self tblMain]];
    
        //If section more than section count minus one set at last
        section = section > (sectionCount - 1) ? 2 : section;
    
        [self toggleCollapseSection:section];
    }

    Metodo di cui sopra verrà richiamato quando l’utente tocca a qualsiasi nostra tabella di vista di sezione. Questo metodo di ricerca di sezione corretto il numero in base alle nostre sectionViews array che abbiamo creato prima.

    Abbiamo, inoltre, implementare il metodo per ottenere la quale la sezione di intestazione di vista appartiene.

    - (NSInteger) sectionNumberOfView:(UIView*) view
    {
        UILabel* label = [[view subviews] objectAtIndex:0];
    
        NSInteger sectionNum = 0;
    
        for(UIView* sectionView in [self sectionViews])
        {
            UILabel* sectionLabel = [[sectionView subviews] objectAtIndex:0];
    
            //NSLog(@"Section: %d -> %@ vs %@", sectionNum, [label text], [sectionLabel text]);
    
            if([[label text] isEqualToString:[sectionLabel text]])
            {
                return sectionNum;
            }
    
            sectionNum++;
        }
    
        return NSNotFound;
    }

    Successiva, si deve implementare il metodo toggleCollapseSection:

    - (void) toggleCollapseSection:(NSInteger) section
    {
        if([self isCollapsedSection:section])
        {
            [self removeCollapsedSection:section];
        }
        else
        {
            [self addCollapsedSection:section];
        }
    
        [[self tblMain] reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
    }

    Di questo metodo di inserire/rimuovere la sezione numero della nostra collapsedSections array che abbiamo creato prima. Quando un numero di sezione inserita alla matrice, significa che la sezione deve essere compresso ed espanso nel caso contrario.

    Prossimo attuare removeCollapsedSection:, addCollapsedSection:section e isCollapsedSection:section

    - (BOOL)isCollapsedSection:(NSInteger) section
    {
        for(NSNumber* existing in [self collapsedSections])
        {
            NSInteger current = [existing integerValue];
    
            if(current == section)
            {
                return YES;
            }
        }
    
        return NO;
    }
    
    - (void)removeCollapsedSection:(NSInteger) section
    {
        [[self collapsedSections] removeObjectIdenticalTo:[NSNumber numberWithInteger:section]];
    }
    
    - (void)addCollapsedSection:(NSInteger) section
    {
        [[self collapsedSections] addObject:[NSNumber numberWithInteger:section]];
    }

    Tre metodo è solo aiutanti per renderci più facile accesso collapsedSections array.

    Infine, implementare questa tabella vista delegato, perché la nostra sezione personalizzata vista sembra bello.

    - (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        return 30.f; //Same as each custom section view height
    }

    Speranza che aiuta.

  10. 1

    Ho usato un NSDictionary come datasource, questo sembra un sacco di codice, ma è veramente semplice e funziona molto bene!
    come appare qui

    Ho creato un enum per le sezioni

    typedef NS_ENUM(NSUInteger, TableViewSection) {
    
        TableViewSection0 = 0,
        TableViewSection1,
        TableViewSection2,
        TableViewSectionCount
    };

    sezioni proprietà:

    @property (nonatomic, strong) NSMutableDictionary * sectionsDisctionary;

    Un metodo di restituzione mio sezioni:

    -(NSArray <NSNumber *> * )sections{
    
        return @[@(TableViewSection0), @(TableViewSection1), @(TableViewSection2)];
    }

    E quindi l’installazione miei dati soruce:

    -(void)loadAndSetupData{
    
        self.sectionsDisctionary = [NSMutableDictionary dictionary];
    
        NSArray * sections = [self sections];
    
        for (NSNumber * section in sections) {
    
        NSArray * sectionObjects = [self objectsForSection:section.integerValue];
    
        [self.sectionsDisctionary setObject:[NSMutableDictionary dictionaryWithDictionary:@{@"visible" : @YES, @"objects" : sectionObjects}] forKey:section];
        }
    }
    
    -(NSArray *)objectsForSection:(NSInteger)section{
    
        NSArray * objects;
    
        switch (section) {
    
            case TableViewSection0:
    
                objects = @[] //objects for section 0;
                break;
    
            case TableViewSection1:
    
                objects = @[] //objects for section 1;
                break;
    
            case TableViewSection2:
    
                objects = @[] //objects for section 2;
                break;
    
            default:
                break;
        }
    
        return objects;
    }

    La prossima metodi, vi aiuterà a sapere quando una sezione è aperta, e come rispondere a tableview datasource:

    Rispondere la sezione di datasource:

    /**
     *  Asks the delegate for a view object to display in the header of the specified section of the table view.
     *
     *  @param tableView The table-view object asking for the view object.
     *  @param section   An index number identifying a section of tableView .
     *
     *  @return A view object to be displayed in the header of section .
     */
    - (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    
        NSString * headerName = [self titleForSection:section];
    
        YourCustomSectionHeaderClass * header = (YourCustomSectionHeaderClass *)[tableView dequeueReusableHeaderFooterViewWithIdentifier:YourCustomSectionHeaderClassIdentifier];
    
        [header setTag:section];
        [header addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]];
        header.title = headerName;
        header.collapsed = [self sectionIsOpened:section];
    
    
        return header;
    }
    
    /**
     * Asks the data source to return the number of sections in the table view
     *
     * @param An object representing the table view requesting this information.
     * @return The number of sections in tableView.
     */
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        //Return the number of sections.
    
        return self.sectionsDisctionary.count;
    }
    
    /**
     * Tells the data source to return the number of rows in a given section of a table view
     *
     * @param tableView: The table-view object requesting this information.
     * @param section: An index number identifying a section in tableView.
     * @return The number of rows in section.
     */
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    
        BOOL sectionOpened = [self sectionIsOpened:section];
        return sectionOpened ? [[self objectsForSection:section] count] : 0;
    }

    Strumenti:

    /**
     Return the section at the given index
    
     @param index the index
    
     @return The section in the given index
     */
    -(NSMutableDictionary *)sectionAtIndex:(NSInteger)index{
    
        NSString * asectionKey = [self.sectionsDisctionary.allKeys objectAtIndex:index];
    
        return [self.sectionsDisctionary objectForKey:asectionKey];
    }
    
    /**
     Check if a section is currently opened
    
     @param section the section to check
    
     @return YES if is opened
     */
    -(BOOL)sectionIsOpened:(NSInteger)section{
    
        NSDictionary * asection = [self sectionAtIndex:section];
        BOOL sectionOpened = [[asection objectForKey:@"visible"] boolValue];
    
        return sectionOpened;
    }
    
    
    /**
     Handle the section tap
    
     @param tap the UITapGestureRecognizer
     */
    - (void)handleTapGesture:(UITapGestureRecognizer*)tap{
    
        NSInteger index = tap.view.tag;
    
        [self toggleSection:index];
    }

    Passare sezione visibilità

    /**
     Switch the state of the section at the given section number
    
     @param section the section number
     */
    -(void)toggleSection:(NSInteger)section{
    
        if (index >= 0){
    
            NSMutableDictionary * asection = [self sectionAtIndex:section];
    
            [asection setObject:@(![self sectionIsOpened:section]) forKey:@"visible"];
    
            [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
        }
    }
  11. 0
    //-------------------------------------------------------------------------------
    // tableView:viewForHeaderInSection:
    //-------------------------------------------------------------------------------
    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    
        UIView *mView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 20, 20)];
        [mView setBackgroundColor:[UIColor greenColor]];
    
        UIImageView *logoView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 5, 20, 20)];
        [logoView setImage:[UIImage imageNamed:@"carat.png"]];
        [mView addSubview:logoView];
    
        UIButton *bt = [UIButton buttonWithType:UIButtonTypeCustom];
        [bt setFrame:CGRectMake(0, 0, 150, 30)];
        [bt setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [bt setTag:section];
        [bt.titleLabel setFont:[UIFont systemFontOfSize:20]];
        [bt.titleLabel setTextAlignment:NSTextAlignmentCenter];
        [bt.titleLabel setTextColor:[UIColor blackColor]];
        [bt setTitle: @"More Info" forState: UIControlStateNormal];
        [bt addTarget:self action:@selector(addCell:) forControlEvents:UIControlEventTouchUpInside];
        [mView addSubview:bt];
        return mView;
    
    }
    
    #pragma mark - Suppose you want to hide/show section 2... then
    #pragma mark  add or remove the section on toggle the section header for more info
    
    - (void)addCell:(UIButton *)bt{
    
        //If section of more information
        if(bt.tag == 2) {
    
            //Initially more info is close, if more info is open
            if(ifOpen) {
                DLog(@"close More info");
    
                //Set height of section
                heightOfSection = 0.0f;
    
                //Reset the parameter that more info is closed now
                ifOpen = NO;
            }else {
                //Set height of section
                heightOfSection = 45.0f;
                //Reset the parameter that more info is closed now
                DLog(@"open more info again");
                ifOpen = YES;
            }
            //[self.tableView reloadData];
            [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade];
        }
    
    }//end addCell
    #pragma mark -
    #pragma mark  What will be the height of the section, Make it dynamic
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    
        if (indexPath.section == 2) {
            return heightOfSection;
        }else {
            return 45.0f;
        }

    //vKj

  12. 0
    This action will happen in your didSelectRowAtIndexPath, when you will try to hide or show number of cell in a  section
    
    first of all declare a global variable numberOfSectionInMoreInfo in .h file and in your viewDidLoad set suppose to numberOfSectionInMoreInfo = 4.
    
    Now use following logic: 
    
    
     //More info link
            if(row == 3) {
    
                /*Logic: We are trying to hide/show the number of row into more information section */
    
                NSString *log= [NSString stringWithFormat:@"Number of section in more %i",numberOfSectionInMoreInfo];
    
                [objSpineCustomProtocol showAlertMessage:log];
    
                //Check if the number of rows are open or close in view
                if(numberOfSectionInMoreInfo > 4) {
    
                    //close the more info toggle
                    numberOfSectionInMoreInfo = 4;
    
                }else {
    
                    //Open more info toggle
                    numberOfSectionInMoreInfo = 9;
    
                }
    
                //reload this section
                [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];

    //vKj

    • Perché due risposte? Non mi sembra di aver fornito due diverse soluzioni al problema.
  13. 0

    Espansione questo risposta scritta in Objective C, ho scritto la seguente per chi è iscritto in Swift

    L’idea è di utilizzare le sezioni all’interno della tabella e impostare il numero di righe nella sezione 1 (compresso) e 3(espansa), quando la prima riga in che sezione è sfruttato

    La tabella che determina il numero di righe per disegnare basato su una matrice di valori Booleani

    Devi creare due righe in storyboard e dare loro il riutilizzo identificatori ‘CollapsingRow’ e ‘GroupHeading’

    import UIKit
    
    class CollapsingTVC:UITableViewController{
    
        var sectionVisibilityArray:[Bool]!//Array index corresponds to section in table
    
        override func viewDidLoad(){
            super.viewDidLoad()
            sectionVisibilityArray = [false,false,false]
        }
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
        }
    
        override func numberOfSections(in tableView: UITableView) -> Int{
            return sectionVisibilityArray.count
        }
        override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat{
            return 0
        }
    
        //numberOfRowsInSection - Get count of entries
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            var rowsToShow:Int = 0
            if(sectionVisibilityArray[section]){
                rowsToShow = 3 //Or however many rows should be displayed in that section
            }else{
                rowsToShow = 1
            }
            return rowsToShow
        }//numberOfRowsInSection
    
    
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
            if(indexPath.row == 0){
                if(sectionVisibilityArray[indexPath.section]){
                    sectionVisibilityArray[indexPath.section] = false
                }else{
                    sectionVisibilityArray[indexPath.section] = true
                }
                self.tableView.reloadSections([indexPath.section], with: .automatic)
            }
        }
    
        //cellForRowAtIndexPath - Get table cell corresponding to this IndexPath
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
            var cell:UITableViewCell
    
            if(indexPath.row == 0){
                 cell = tableView.dequeueReusableCell(withIdentifier: "GroupHeading", for: indexPath as IndexPath)
            }else{
                cell = tableView.dequeueReusableCell(withIdentifier: "CollapsingRow", for: indexPath as IndexPath)
            }
    
            return cell
    
        }//cellForRowAtIndexPath
    
    }
  14. 0

    Qualche esempio di codice per l’animazione di un’azione espandi/comprimi utilizzando una tabella in visualizzazione intestazione di sezione è fornito da Apple a Tabella di Visualizzazione delle Animazioni e dei Gesti.

    La chiave di questo approccio è quello di implementare

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

    e di ritorno personalizzato UIView che include un pulsante (in genere la stessa dimensione come l’intestazione di vista). Sottoclasse di UIView e l’utilizzo che per la visualizzazione dell’intestazione (come in questo esempio), si può facilmente memorizzare altri dati come il numero della sezione.

  15. 0

    Ho fatto la stessa cosa usando più sezioni .

    class SCTierBenefitsViewController: UIViewController {
        @IBOutlet private weak var tblTierBenefits: UITableView!
        private var selectedIndexPath: IndexPath?
        private var isSelected:Bool = false
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            tblTierBenefits.register(UINib(nibName:"TierBenefitsTableViewCell", bundle: nil), forCellReuseIdentifier:"TierBenefitsTableViewCell")
            tblTierBenefits.register(UINib(nibName:"TierBenefitsDetailsCell", bundle: nil), forCellReuseIdentifier:"TierBenefitsDetailsCell")
    
            tblTierBenefits.rowHeight = UITableViewAutomaticDimension;
            tblTierBenefits.estimatedRowHeight = 44.0;
            tblTierBenefits.tableFooterView = UIView()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    
    }
    
    extension SCTierBenefitsViewController : UITableViewDataSource{
    
        func numberOfSections(in tableView: UITableView) -> Int {
            return 7
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return (isSelected && section == selectedIndexPath?.section) ? 2 : 1 
        }
    
        func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return  0.01
        }
    
        func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            return nil
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            switch indexPath.row {
            case 0:
                let cell:TierBenefitsTableViewCell = tableView.dequeueReusableCell(withIdentifier: "TierBenefitsTableViewCell")! as! TierBenefitsTableViewCell
                cell.selectionStyle = .none
                cell.contentView.setNeedsLayout()
                cell.contentView.layoutIfNeeded()
                return cell
    
            case 1:
                let cell:TierBenefitsDetailsCell = tableView.dequeueReusableCell(withIdentifier: "TierBenefitsDetailsCell")! as! TierBenefitsDetailsCell
                cell.selectionStyle = .none
                return cell
    
            default:
                break
            }
    
            return UITableViewCell()
        }
    }
    
    extension SCTierBenefitsViewController : UITableViewDelegate{
    
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            if indexPath.row == 0 {
    
                if let _selectedIndexPath = selectedIndexPath ,selectedIndexPath?.section == indexPath.section {
                    tblTierBenefits.beginUpdates()
                    expandCollapse(indexPath: _selectedIndexPath, isExpand: false)
                    selectedIndexPath = nil
                }
                else{
                    tblTierBenefits.beginUpdates()
                    if selectedIndexPath != nil {
                        tblTierBenefits.reloadSections([(selectedIndexPath?.section)!], with: .none)
                    }
                    expandCollapse(indexPath: indexPath, isExpand: true)
                }
            }
        }
    
        private func  expandCollapse(indexPath: IndexPath?,isExpand: Bool){
            isSelected = isExpand
            selectedIndexPath = indexPath
            tblTierBenefits.reloadSections([(indexPath?.section)!], with: .none)
            tblTierBenefits.endUpdates()
        }
    
    }
  16. 0

    Io sono l’aggiunta di questa soluzione per la completezza e che mostra come lavorare con le intestazioni di sezione.

    import UIKit
    
    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
        @IBOutlet var tableView: UITableView!
        var headerButtons: [UIButton]!
        var sections = [true, true, true]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            tableView.dataSource = self
            tableView.delegate = self
    
            let section0Button = UIButton(type: .detailDisclosure)
            section0Button.setTitle("Section 0", for: .normal)
            section0Button.addTarget(self, action: #selector(section0Tapped), for: .touchUpInside)
    
            let section1Button = UIButton(type: .detailDisclosure)
            section1Button.setTitle("Section 1", for: .normal)
            section1Button.addTarget(self, action: #selector(section1Tapped), for: .touchUpInside)
    
            let section2Button = UIButton(type: .detailDisclosure)
            section2Button.setTitle("Section 2", for: .normal)
            section2Button.addTarget(self, action: #selector(section2Tapped), for: .touchUpInside)
    
            headerButtons = [UIButton]()
            headerButtons.append(section0Button)
            headerButtons.append(section1Button)
            headerButtons.append(section2Button)
        }
    
        func numberOfSections(in tableView: UITableView) -> Int {
            return sections.count
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return sections[section] ? 3 : 0
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cellReuseId = "cellReuseId"
            let cell = UITableViewCell(style: .default, reuseIdentifier: cellReuseId)
            cell.textLabel?.text = "\(indexPath.section): \(indexPath.row)"
            return cell
        }
    
        func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            return headerButtons[section]
        }
    
        func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return 44
        }
    
        @objc func section0Tapped() {
            sections[0] = !sections[0]
            tableView.reloadSections([0], with: .fade)
        }
    
        @objc func section1Tapped() {
            sections[1] = !sections[1]
            tableView.reloadSections([1], with: .fade)
        }
    
        @objc func section2Tapped() {
            sections[2] = !sections[2]
            tableView.reloadSections([2], with: .fade)
        }
    
    }

    Link per gist: https://gist.github.com/pawelkijowskizimperium/fe1e8511a7932a0d40486a2669316d2c

  17. 0

    a sostegno di @jean.timex soluzione, utilizzare il codice di seguito se si desidera aprire una sezione in qualsiasi momento. creare una variabile come: var expandedSection = -1;

    func toggleSection(_ header: CollapsibleTableViewHeader, section: Int) {
        let collapsed = !sections[section].collapsed
        //Toggle collapse
        sections[section].collapsed = collapsed
        header.setCollapsed(collapsed)
        tableView.reloadSections(NSIndexSet(index: section) as IndexSet, with: .automatic)
        if (expandedSection >= 0 && expandedSection != section){
            sections[expandedSection].collapsed = true
            tableView.reloadSections(NSIndexSet(index: expandedSection) as IndexSet, with: .automatic)
        }
        expandedSection = section;
    }

Lascia un commento