I. Création de cellule personnalisées▲
L'idée ici est de démontrer que nous ne sommes pas cantonnés aux types de cellules disponibles par défaut lorsqu'on construit une table. Il est possible d'être tout à fait original et d'aller beaucoup plus loin. Il s'avère d'ailleurs qu'en pratique, beaucoup d'applications utilisent leurs propres cellules personnalisées pour présenter leurs informations au sein d'une table.
Lorsque vous souhaitez sortir des sentiers battus, que votre designer vous propose une présentation des éléments élaborée, autre que celle livrée de base avec le SDK iOS, il vous faut créer des éléments personnalisés.
Ici nous souhaitons créer des cellules de tableau avec une présentation bien spécifique, pour ce faire, nous allons créer une classe héritant de UITableViewCell.
Dans le répertoire app/views, créons le fichier todo_table_view_cell.rb :
class
TodoTableViewCell <
UITableViewCell
TODO_CELL_REUSE_ID =
"TodoTableViewCell"
attr_accessor :title
, :date
, :priority
end
Nous créons donc une classe héritant de UITableViewCell contenant trois attributs qui serviront pour stocker le titre de la tâche, sa date de création ainsi que sa priorité, ce qui permettra d'afficher un badge en fonction de celle-ci. Vous noterez qu'on définit également une constante qui sera utilisée comme identifiant de réutilisation des cellules comme nous l'avons déjà fait dans l'article précédent.
Jusque-là , nous avons créé nos cellules directement depuis ListViewController en passant par la méthode tableView:cellForRowAtIndexPath:, nous allons maintenant déplacer cette logique dans notre classe dédiée à la création de cellules. Voici donc la méthode à ajouter à TodoTableViewCell :
def
self
.cellForTask(
task, inTableView:
tableView)
cell =
tableView.dequeueReusableCellWithIdentifier(
TODO_CELL_REUSE_ID)
||
TodoTableViewCell.alloc.initWithStyle(
UITableViewCellStyleDefault, reuseIdentifier:
TODO_CELL_REUSE_ID)
cell.title =
task.name
cell.date =
task.created_at
cell.priority =
task.priority
cell.selectionStyle =
UITableViewCellSelectionStyleNone
cell
end
Cette méthode permet de vérifier si la cellule correspondante est cachée. Si elle ne l'est pas, nous la créons.
Nous stockons ensuite le titre, la date de création et la priorité grâce à l'objet task qui a été passé. Nous définissons un style vide pour la cellule puisque nous voulons gérer nous même son aspect visuel. Finalement nous retournons cette cellule.
Il ne nous reste plus qu'à utiliser ces cellules personnalisées dans notre contrôleur ListViewController :
def
tableView(
tableView, cellForRowAtIndexPath:
indexPath)
task =
@tasks
[
indexPath.row]
TodoTableViewCell.cellForTask(
task, inTableView:
tableView)
end
Vous pouvez lancer l'application. Voici ce que vous obtenez :
La table est vide, aucune des cellules n'est remplie. En effet, lorsque vous utilisez des cellules personnalisées, il faut leur préciser comment afficher les informations. Nous allons donc, comme pour n'importe quel UIView, placer nos différent éléments en utilisant la méthode addSubview.
II. Ajout des éléments▲
II-A. Image de fond▲
Les UIView mettent à disposition la méthode layoutSubviews qui permet de définir comment seront disposées les vues enfants, nous allons l'utiliser pour disposer nos informations. Commençons par ajouter une image de fond à nos cellules :
def
layoutSubviews
@background_image
=
UIImageView.alloc.initWithImage(
UIImage.imageNamed(
"bgCell"
))
self
.addSubview(
@background_image
)
end
et dans app/controllers/list_view_controller.rb :
def
tableView(
tableView, heightForRowAtIndexPath:
indexPath)
50
end
Nous ajoutons donc notre image de fond mais comme vous pouvez le remarquer, nous prenons le soin de préciser au contrôleur la hauteur de nos cellules pour qu'elle corresponde à la hauteur de notre image (50px ici). Par défaut, la hauteur appliquée aux cellules est de 44px ce qui masquerait une partie de notre image de fond.
Voici ce que vous obtenez en lançant l'application :
II-B. Nom de la tâche▲
Nous pouvons maintenant passer à l'ajout du nom de la tâche dans la cellule. Pour ce faire, nous allons enrichir la méthode layoutSubviews et ajouter une méthode dédiée à la création du label :
def
layoutSubviews
@background_image
=
UIImageView.alloc.initWithImage(
UIImage.imageNamed(
"bgCell"
))
self
.addSubview(
@background_image
)
self
.addSubview(
titleLabel)
end
def
titleLabel
titleLabel =
UILabel.alloc.initWithFrame([[
10
, 0
]
, [
300
, 40
]])
titleLabel.font =
UIFont.fontWithName(
"AmericanTypewriter-Bold"
, size:
18
)
titleLabel.textColor =
UIColor.blueColor
titleLabel.adjustsFontSizeToFitWidth =
true
titleLabel.backgroundColor =
UIColor.clearColor
titleLabel.text =
@title
titleLabel
end
Voici le résultat :
II-C. Ajout de la date▲
Aucune surprise ici puisque le principe va être exactement le même que pour l'ajout du nom de la tâche :
def
layoutSubviews
@background_image
=
UIImageView.alloc.initWithImage(
UIImage.imageNamed(
"bgCell"
))
self
.addSubview(
@background_image
)
self
.addSubview(
titleLabel)
self
.addSubview(
dateLabel)
end
def
dateLabel
dateLabel =
UILabel.alloc.initWithFrame([[
10
, 10
]
, [
300
, 40
]])
dateLabel.font =
UIFont.fontWithName(
"AmericanTypewriter-Bold"
, size:
14
)
dateLabel.textColor =
UIColor.blackColor
dateLabel.adjustsFontSizeToFitWidth =
true
dateLabel.backgroundColor =
UIColor.clearColor
dateLabel.text =
@date
.strftime(
"%d/%M/%Y"
)
dateLabel
end
II-D. Ajout du marqueur de priorité▲
Nous allons maintenant ajouter à droite dans notre cellule un marqueur de priorité qui sera représenté par une image que nous ajoutons donc à notre dossier resources. Ce marqueur ne sera à afficher que si la tâche est en priorité haute :
def
layoutSubviews
@background_image
=
UIImageView.alloc.initWithImage(
UIImage.imageNamed(
"bgCell"
))
self
.addSubview(
@background_image
)
self
.addSubview(
titleLabel)
self
.addSubview(
dateLabel)
self
.addSubview(
priorityImage)
if
@priority
==
"Haut"
end
def
priorityImage
priorityImage =
UIImageView.alloc.initWithImage(
UIImage.imageNamed(
"important"
))
priorityImage.frame =
([[
290
, 8
]
, [
29
, 29
]])
priorityImage
end
La méthode d'ajout de l'image n'est appelée que si notre tâche en cours de rendu à une priorité haute, information que nous stockons dans une variable d'instance à la création d'une nouvelle cellule personnalisée.
Voyons un exemple de rendu avec deux tâches en priorité basse et une en priorité haute :
III. Conclusion▲
Nous avons vu dans cet article comment mettre en place un UITableViewCell pour pouvoir dépasser les limites des types de cellule disponibles par défaut. Vous pouvez donc exploiter cette possibilité pour intégrer un design personnalisé et mettre en œuvre toutes vos idées.
Un exercice intéressant pourrait être d'ajouter un bouton dans la cellule qui permettrait de modifier le statut (fait / à faire) de la tâche. Le bouton serait représenté par deux images qui alterneraient en fonction du statut.
Vous trouverez l'ensemble du code d'exemple de cet article, découpé en commits, sur GitHub.
IV. Remerciements▲
Cet article est publié avec l'aimable autorisation de Synbioz, l'article original peut être lu sur le blog de Synbioz : RubyMotion - les cellules personnalisées.