tutorial - UITableview con más de una celda personalizada con Swift
uitableview tutorial swift 4 (4)
Quiero usar una UITableview con diferentes tableViewCells personalizados. Mis 3 células son como tales:
- Cell1: debe tener una imagen y una etiqueta.
- Cell2: debe tener dos etiquetas.
- Cell3: debería tener un dayPicker.
No quiero codificar una etiqueta para las celdas. ¿Cómo puedo manejar esto en Swift? ¿Tengo que codificar mi propia clase para cada celda? ¿Puedo usar un tableviewController? ¿Cómo puedo llenar datos en diferentes celdas?
Me gustaría generar un TableView, como una aplicación de contacto de un dispositivo iOS.
Actualización de Swift 3.0 + con código mínimo
Concepto básico: crear una vista de tabla con prototipos dinámicos de células. Asigne un identificador y cree una clase de celda de vista de tabla personalizada para cada prototipo de celda. Inicie y muestre celdas personalizadas en el método delegado de la vista de tabla.
1. Crear celdas en el guión gráfico
Arrastre un tableView a su controlador de vista, agregue celdas prototipo y luego suelte el elemento de la interfaz de usuario en sus celdas de vista de tabla, agregue la restricción correctamente si es necesario.
2. Crear clases personalizadas
UITableViewCell
Agregue el siguiente código a su proyecto. Lo estoy colocando justo encima de la clase de controlador de vista.
class FirstTableCell: UITableViewCell {
}
class SecondTableCell: UITableViewCell {
}
class ThirdTableCell: UITableViewCell {
}
3. Asignar clase personalizada e identificador a los prototipos de celda
Para cada uno de los prototipos de celda en el guión gráfico, asigne la clase personalizada creada a partir del paso 2 y luego ingrese un identificador único.
4. Conecte los elementos de la IU al código rápido
Control arrastre la vista de tabla y conéctese a la clase de controlador de vista. Control arrastre los elementos de la interfaz de usuario que se agregan a los prototipos de celda en el paso 1 y conéctese a la clase de celda de vista de tabla correspondiente.
5. Agregue código para ver el controlador y controlar la vista de tabla
Haga que su controlador de vista se ajuste al delegado de vista de tabla
class YourViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
En
viewDidLoad
, configure el delegado y la fuente de datos de la vista de tabla.
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.dataSource = self
self.tableView.delegate = self
}
Finalmente, agregue dos métodos delegados para controlar su vista de tabla, según el requisito mínimo.
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. Pruébalo :)
Las respuestas anteriores son las mejores respuestas, pero hay TONELADAS de razones para obtener este problema. Aquí hay otra solución potencial para cualquier persona con este problema:
Mi problema era que estaba pasando a la clase ViewController y no a la vista del guión gráfico. Entonces mi referencia a la celda del guión gráfico no tenía sentido, ya que el guión gráfico no se estaba utilizando.
Estaba haciendo esto:
let viewControllerB = SubViewController()
viewControllerB.passedData = diseases[indexPath.row].name
navigationController?.pushViewController(viewControllerB, animated: true)
Y necesitaba hacer algo como esto:
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)
Espero que esto ayude a alguien.
Permítanme comenzar respondiendo sus preguntas primero.
¿Tengo que codificar una clase propia para cada celda? => Sí, creo que sí. Al menos, lo haría de esa manera.
¿Puedo usar un tableviewController? => Sí, puedes. Sin embargo, también puede tener una vista de tabla dentro de su controlador de vista.
¿Cómo puedo llenar datos en diferentes celdas? => Dependiendo de las condiciones, puede completar datos en diferentes celdas. Por ejemplo, supongamos que desea que sus dos primeras filas sean como el primer tipo de celdas. Entonces, simplemente crea / reutiliza el primer tipo de celdas y establece sus datos. Será más claro, cuando te muestro las capturas de pantalla, supongo.
Déjame darte un ejemplo con un TableView dentro de un ViewController. Una vez que comprenda el concepto principal, puede intentar modificarlo de la forma que desee.
Paso 1: Cree 3 TableViewCells personalizados. Lo llamé FirstCustomTableViewCell, SecondCustomTableViewCell, ThirdCustomTableViewCell. Deberías usar nombres más significativos.
Paso 2: vaya al Main.storyboard y arrastre y suelte un TableView dentro de su View Controller. Ahora, seleccione la vista de tabla y vaya al inspector de identidad. Establezca "Prototype Cells" en 3. Aquí, acaba de decirle a su TableView que puede tener 3 tipos diferentes de celdas.
Paso 3: Ahora, seleccione la primera celda en su TableView y en el inspector de identidad, coloque "FirstCustomTableViewCell" en el campo Clase personalizada y luego configure el identificador como "firstCustomCell" en el inspector de atributos.
Haga lo mismo para todos los demás: establezca sus clases personalizadas como "SecondCustomTableViewCell" y "ThirdCustomTableViewCell" respectivamente. Establezca también los identificadores como secondCustomCell y thirdCustomCell consecutivamente.
Paso 4: edite las clases de celdas personalizadas y agregue salidas según sus necesidades. Lo edité según tu pregunta.
PD: debe poner los puntos de venta bajo la definición de clase.
Entonces, en FirstCustomTableViewCell.swift, debajo de
class FirstCustomTableViewCell: UITableViewCell {
pondrías tu etiqueta y puntos de vista de imagen.
@IBOutlet weak var myImageView: UIImageView!
@IBOutlet weak var myLabel: UILabel!
y en SecondCustomTableViewCell.swift, agregue las dos etiquetas como-
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)
}
}
y ThirdCustomTableViewCell.swift debería verse como:
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)
}
}
Paso 5: en su ViewController, cree un Outlet para su TableView y configure la conexión desde el guión gráfico. Además, debe agregar UITableViewDelegate y UITableViewDataSource en la definición de clase como la lista de protocolos. Entonces, su definición de clase debería verse como:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
Después de eso, adjunte el UITableViewDelegate y el UITableViewDatasource de su vista de tabla a su controlador. En este punto, su viewController.swift debería verse como:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
PD: Si tuviera que usar un TableViewController en lugar de un TableView dentro de un ViewController, podría haber omitido este paso.
Paso 6: Arrastre y suelte las vistas de imagen y las etiquetas en su celda de acuerdo con la clase Cell. y luego proporcionar conexión a sus salidas desde el guión gráfico.
Paso 7: Ahora, escriba los métodos requeridos de UITableViewDatasource en el controlador de vista.
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()
}
}
UITableViewController
hereda
UIViewController
que ya tiene
UITableviewDataSource
y
UITableviewDelegate
en sí mismo.
Puede subclasificar
UITableViewController
o usar un
TableView
dentro de su
ViewController
.
Después de eso, debe implementar los métodos necesarios (
cellForRowAtIndexPath
and numberOfRowsInSection
) que se declaran en
UITableviewDataSource
.
También en el guión gráfico, debe crear prototipos de células con Id único.
Existen tipos básicos de celdas, con (título, subtítulo, por ejemplo); también puede usarlos si no necesita una configuración especial.
Entonces, para el selector, sí, debe crear su propia celda personalizada.
Cree el selector de fecha de retención de clase
UITableViewCell
personalizado necesario y asegúrese de usar delegado para devolver el resultado deseado a su
ViewController
.