UITableview con più di una cella personalizzata con Swift


111

Voglio usare un UITableview con diversi tableViewCells personalizzati. Le mie 3 celle sono come tali:

  • Cella1: dovrebbe avere un'immagine e un'etichetta.
  • Cell2: dovrebbe avere due etichette.
  • Cell3: dovrebbe avere un dayPicker.

Non voglio codificare un tag per le celle. Come posso gestirlo in Swift. Devo codificare la mia classe per ogni cella? Posso usare un tableviewController? Come posso popolare i dati in celle diverse?

Vorrei generare un tableView, come un'app di contatto di un dispositivo iOS.



Risposte:


270

Vorrei iniziare rispondendo prima alle tue domande.

Devo codificare una classe per ogni cella? => Sì, credo di sì. Almeno, lo farei in questo modo.

Posso usare un tableviewController? => Sì, puoi. Tuttavia, puoi anche avere una vista tabella all'interno del controller della vista.

Come posso popolare i dati in celle diverse? => A seconda delle condizioni, è possibile popolare i dati in celle diverse. Ad esempio, supponiamo che tu voglia che le tue prime due righe siano come il primo tipo di celle. Quindi, devi solo creare / riutilizzare il primo tipo di celle e impostare i suoi dati. Sarà più chiaro quando ti mostrerò le schermate, immagino.

Lascia che ti faccia un esempio con un TableView all'interno di un ViewController. Una volta compreso il concetto principale, puoi provare a modificarlo come preferisci.

Passaggio 1: creare 3 TableViewCell personalizzate. L'ho chiamato FirstCustomTableViewCell, SecondCustomTableViewCell, ThirdCustomTableViewCell. Dovresti usare nomi più significativi.

inserisci qui la descrizione dell'immagine

Passaggio 2: vai su Main.storyboard e trascina e rilascia un TableView all'interno del tuo View Controller. Ora seleziona la vista tabella e vai all'ispettore identità. Impostare "Prototype Cells" su 3. Qui, hai appena detto al tuo TableView che potresti avere 3 diversi tipi di celle.

inserisci qui la descrizione dell'immagine

Passaggio 3: ora, seleziona la prima cella nel tuo TableView e nell'Ispettore di identità, metti "FirstCustomTableViewCell" nel campo della classe personalizzata e quindi imposta l'identificatore come "firstCustomCell" nell'ispettore degli attributi.

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Fai lo stesso per tutti gli altri: imposta le classi personalizzate come "SecondCustomTableViewCell" e "ThirdCustomTableViewCell" rispettivamente. Impostare anche gli identificatori come secondCustomCell e thirdCustomCell consecutivamente.

Passaggio 4: modifica le classi di celle personalizzate e aggiungi punti vendita in base alle tue necessità. L'ho modificato in base alla tua domanda.

PS: devi mettere i punti vendita sotto la definizione di classe.

Quindi, nel FirstCustomTableViewCell.swift, sotto

class FirstCustomTableViewCell: UITableViewCell {

metteresti la tua etichetta e punti vendita di visualizzazione delle immagini.

 @IBOutlet weak var myImageView: UIImageView!
 @IBOutlet weak var myLabel: UILabel!

e in SecondCustomTableViewCell.swift, aggiungi le due etichette come-

import UIKit

class SecondCustomTableViewCell: UITableViewCell {

    @IBOutlet weak var myLabel_1: UILabel!
    @IBOutlet weak var myLabel_2: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

e ThirdCustomTableViewCell.swift dovrebbe essere simile a:

import UIKit

class ThirdCustomTableViewCell: UITableViewCell {

    @IBOutlet weak var dayPicker: UIDatePicker!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

Passaggio 5: nel tuo ViewController, crea un outlet per il tuo TableView e imposta la connessione dallo storyboard. Inoltre, è necessario aggiungere UITableViewDelegate e UITableViewDataSource nella definizione della classe come elenco di protocolli. Quindi, la definizione della tua classe dovrebbe assomigliare a:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

Successivamente, collega UITableViewDelegate e UITableViewDatasource della visualizzazione tabella al controller. A questo punto il tuo viewController.swift dovrebbe apparire come:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

PS: se avessi utilizzato un TableViewController anziché un TableView all'interno di un ViewController, avresti potuto saltare questo passaggio.

Passaggio 6: trascina e rilascia le visualizzazioni e le etichette dell'immagine nella cella in base alla classe Cell. e quindi fornire la connessione ai loro punti vendita dallo storyboard.

Passaggio 7: ora, scrivi i metodi richiesti di UITableViewDatasource nel controller di visualizzazione.

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "firstCustomCell")
            //set the data here
            return cell
        }
        else if indexPath.row == 1 {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "secondCustomCell")
            //set the data here
            return cell
        }
        else {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "thirdCustomCell")
            //set the data here
            return cell
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

1
Ricevo il messaggio: "Impossibile eseguire il cast del valore di tipo" UITableViewCell "(0x1dfbfdc) a" Projekt.TitelTableViewCell "(0x89568)" nel func cellForRowAtIndexPath. Sto usando un UITableViewController e ho una classe "TitelTableViewCell" per la mia cella personalizzata "TitelZelle", che ho impostato nell'ispettore di identità della cella "TitelZelle". Cosa devo fare?
Easyglider

Ho lanciato il mio cellulare come! TitelTableViewCell per popolare i miei elementi dell'interfaccia utente personalizzati in questa cella.
Easyglider

7
prova questo => let cell = tableView.dequeueReusableCellWithIdentifier ("TitelZelle", forIndexPath: indexPath) come TitelTableViewCell
Natasha

2
@PradipKumar, qual è il problema? Qual è il tuo errore? A proposito, dovresti fare una domanda se hai qualche domanda. Il commento dovrebbe aiutare a capire o chiarire questo riguardo al problema particolare, ha pubblicato l'autore. Se hai un problema, dovresti andare a fare una domanda e iniziare il tuo post.
Natasha

1
numberOfRowsInSection aiuta la tableview a determinare quante righe vogliamo. Quindi, dovresti fornire solo una clausola che aiuterà il metodo a determinare il numero di righe. indexpath.row == 0 significa che hai già una riga ma in quel momento, la tua tabella non sa se ha una riga o meno. Quindi, dovresti fare così.
Natasha

32

Swift 3.0 + aggiornamento con codice minimo

Concetto di base: creare una vista tabella con prototipi di celle dinamiche. Assegna un identificatore e crea una classe di celle con visualizzazione tabella personalizzata per ogni prototipo di cella. Avvia e mostra celle personalizzate nel metodo delegato della vista tabella.

1. Crea celle sullo storyboard

Trascina un tableView nel controller della vista, aggiungi celle prototipo ad esso, quindi rilascia l'elemento dell'interfaccia utente nelle celle della vista tabella, aggiungi il vincolo correttamente se necessario.

inserisci qui la descrizione dell'immagine

2. Crea UITableViewCellclassi personalizzate

Aggiungi il codice seguente al tuo progetto. Lo metto proprio sopra la classe del controller di visualizzazione.

class FirstTableCell: UITableViewCell {
}

class SecondTableCell: UITableViewCell {
}

class ThirdTableCell: UITableViewCell {   
}

3. Assegnare una classe e un identificatore personalizzati ai prototipi di celle

Per ciascuno dei prototipi di cella nello storyboard, assegna la classe personalizzata creata dal passaggio 2, quindi inserisci un identificatore univoco.

inserisci qui la descrizione dell'immagine

4. Collega gli elementi dell'interfaccia utente al codice swift

Control trascina la vista tabella e connettiti alla classe del controller di visualizzazione. Controllo trascina gli elementi dell'interfaccia utente che vengono aggiunti ai prototipi di cella nel passaggio 1 e connettiti alla classe di cella della vista tabella corrispondente.

inserisci qui la descrizione dell'immagine

5. Aggiungere il codice per visualizzare il controller e controllare la visualizzazione tabella

Rendi il controller della vista conforme al delegato della vista tabella

class YourViewController: UIViewController, UITableViewDataSource, UITableViewDelegate

In viewDidLoad, configura il delegato e l'origine dati della vista tabella.

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.dataSource = self
    self.tableView.delegate = self

}

Infine, aggiungi due metodi delegati per controllare la visualizzazione della tabella, secondo il requisito minimo.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 3
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "firstTableCell") as! FirstTableCell
        // Set up cell.label
        return cell
    } else if indexPath.row == 1 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "secondTableCell") as! SecondTableCell
        // Set up cell.button
        return cell
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "thirdTableCell") as! ThirdTableCell
        // Set up cell.textField
        return cell
    }
}

6. Provalo :)

inserisci qui la descrizione dell'immagine


Fantastico! Adoro le tue animazioni.
iphaaw

Potresti dirmi, è possibile inserire un'intestazione per ogni cella? se é cosi, come?
Pruthvi Hariharan

@PruthviHariharan se vuoi avere un '"intestazione" per ciascuna o la maggior parte delle tue celle, non è una buona idea implementare una cella di intestazione o intestazioni di sezione, che richiedono più codice da gestire e influenzeranno le prestazioni. Il mio suggerimento è di mettere una vista sopra il tuo prototipo di cella e farlo sembrare un "header"
Fangming

@FangmingNing Potresti spiegare con un piccolo esempio. Grazie
Pruthvi Hariharan

Non è necessario il passaggio 5 se si utilizza UITableViewController invece di UIViewController.
Deepak Thakur

0

Le risposte di cui sopra sono le migliori risposte, ma ci sono TANTISSIMI motivi per ottenere questo problema. Ecco un'altra potenziale soluzione per chiunque abbia questo problema:

Il mio problema era che stavo seguendo la classe ViewController e non la visualizzazione dello storyboard. Quindi il mio riferimento alla cella dello storyboard era privo di significato, poiché lo storyboard non veniva utilizzato.

Stavo facendo questo:

let viewControllerB = SubViewController()
viewControllerB.passedData = diseases[indexPath.row].name
navigationController?.pushViewController(viewControllerB, animated: true)

E dovevo fare qualcosa del genere:

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "SubViewStoryboardController") as! SubViewController
nextViewController.passedData = diseases[indexPath.row].name
self.present(nextViewController, animated:true, completion:nil)

Spero che questo aiuti qualcuno.


-22

UITableViewControllersta ereditando UIViewControllerche ha già UITableviewDataSource& UITableviewDelegatemappato su se stesso.

Potresti sottoclasse UITableViewControllero usare un file TableViewall'interno del tuo ViewController. Dopodiché è necessario implementare i metodi richiesti ( cellForRowAtIndexPath and numberOfRowsInSection) dichiarati nel file UITableviewDataSource.

Anche nello storyboard, è necessario creare prototipi di celle con ID univoco.

Esistono tipi base di celle, con (titolo, sottotitolo per esempio) - puoi usarli anche se non hai bisogno di una configurazione speciale.

Quindi, per il selettore, sì, devi creare la tua cella personalizzata. Crea il UITableViewCellselettore di date per la tenuta della classe personalizzata necessaria e assicurati di utilizzare delegato per inviare di nuovo il risultato desiderato al tuo ViewController.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.