Je suis chargé de concevoir un cadre d'application qui permettra à chaque implémentation de personnaliser des parties de l'interface utilisateur. Un tel exemple serait que l'implémentation (appelons-la désormais client) peut définir les cellules de la vue de collection à renvoyer pour un écran particulier. Le cadre est simplement responsable de la vente des objets appropriés pour faciliter la construction d'une application, car nous allons créer plusieurs instances similaires.
Mon approche actuelle du cadre a été de concevoir un contrôleur de coordination qui est responsable de tous les événements de présentation et de licenciement dans l'application. Le contrôleur de coordination par défaut distribue tous les contrôleurs de vue par défaut à l'intérieur du cadre qui effectuent tous leurs tâches pertinentes sans nécessairement fournir une interface utilisateur configurée. Par exemple: un contrôleur affichera une vue de collection avec des cellules de modèle et rien de spécial. L'avantage de cette conception est qu'elle supprime le couplage entre les contrôleurs et permet également à un client de remplacer le coordinateur par défaut et de renvoyer un contrôleur de vue entièrement nouveau pour une tâche spécifique.
Le problème que j'ai est de savoir comment concevoir ce cadre pour permettre à un client d'ajouter sa propre interface utilisateur personnalisée dans l'application.
Première approche
Faites en sorte que le framework nécessite une fabrique de vues et laissez cette fabrique de vues être chargée de distribuer toutes les vues pertinentes. Ainsi, dans le délégué d'application, nous pourrions imposer que le client crée un CollectionViewCellFactory par exemple et que l'interface définit toutes les cellules que toute classe conforme devra fournir. J'ai hérité d'une base de code avec cette conception et je m'en suis éloignée car elle était beaucoup trop abstraite et personnalisable. Il est venu avec des tonnes d'usines pour chaque aspect de l'application et cela a ajouté des jours au temps de configuration de chaque application.
Deuxième approche
Chaque contrôleur de vue spécifie des crochets de sous-classe ou une API de configuration qui permettront à ces classes d'interface utilisateur personnalisées d'être définies au moment de l'exécution (similaire à la façon dont UISplitViewController permet aux appelants de configurer les contrôleurs à l'aide de la propriété viewControllers). Pour ce faire, chaque client sous-classera simplement le contrôleur de coordination de base et dans chaque présentation de contrôleurs; définissez les valeurs appropriées sur le contrôleur afin qu'il atteigne l'interface utilisateur souhaitée. Quelque chose comme
viewController.registerReusableCellsBlock = ^(UICollectionView *collectionView){
//perform custom registration
}
viewController.cellDequeueBlock = ^UICollectionViewCell<SomeProtocol> *(UICollectionView *collectionView,NSIndexPath *indexPath){
//dequeue custom cells
}
Actuellement, je sépare la source de données d'une vue dans un objet distinct pour promouvoir la réutilisabilité et empêcher le ballonnement de ViewController. Cela rend le sous-classement du contrôleur de vue pour fournir l'interface des cellules un peu plus difficile mais pas impossible.
Approche 3
C'est peut-être une mauvaise idée d'essayer de concevoir un cadre et d'anticiper son utilisation. La meilleure option est peut-être de permettre un sous-classement avec un contrôle maximal, même si le coût de configuration est relativement élevé. Ensuite, une fois que je l'ai créé pour plusieurs clients, je peux remarquer les modèles qui émergent et commencer l'optimisation le long de l'itinéraire.
Je comprends comment je pourrais le rendre personnalisable en interne au framework, ce qui me pose problème, c'est comment définir au mieux une interface qui définit les points de personnalisation potentiels du framework par le client.
TL; DR
La partie la plus compliquée de l'interface concerne une vue de collection imbriquée dans les cellules de vue de collection. Cela permet la pagination horizontale et le défilement vertical des cellules. Pour ce faire, une seule source de données gère les cellules horizontales et configure la vue de collecte de chaque cellule avec une nouvelle source de données.
Comment concevoir une interface permettant à toutes ces cellules d'être personnalisables?