Fui encarregado de projetar uma estrutura de aplicativo que permitirá que cada implementação personalize partes da interface do usuário. Um exemplo seria que a implementação (vamos chamá-lo de cliente a partir de agora) pode definir as células da exibição de coleção para retornar para uma tela específica. A estrutura é simplesmente responsável por vender os objetos apropriados para facilitar a criação de um aplicativo, já que criaremos várias instâncias de aparência semelhante.
Minha abordagem atual da estrutura foi projetar um Controlador de Coordenação responsável por todos os eventos de apresentação e dispensa em todo o aplicativo. O Controlador de Coordenação padrão vende todos os controladores de exibição padrão dentro da estrutura que executam suas tarefas relevantes sem necessariamente fornecer a interface do usuário configurada. Por exemplo: um controlador mostrará uma exibição de coleção com células de modelo e nada de especial. O benefício desse design é que ele remove o acoplamento entre controladores e também permite que um cliente substitua o coordenador padrão e retorne um controlador de visualização totalmente novo para uma tarefa específica.
O problema que estou enfrentando é como devo projetar essa estrutura para permitir que um cliente adicione sua própria interface de usuário personalizada ao aplicativo.
Abordagem Um
Faça com que a estrutura exija uma fábrica de vistas e deixe que esta seja responsável por vender todas as vistas relevantes. Portanto, no App Delegate, podemos aplicar que o cliente crie um CollectionViewCellFactory, por exemplo, e a interface defina todas as células que qualquer classe em conformidade precisará fornecer. Eu herdei uma base de código com esse design e me afastei dela, pois era muito abstrata e personalizável. Ele veio com toneladas de fábricas para todos os aspectos do aplicativo e isso acrescentou dias ao tempo de configuração de cada aplicativo.
Abordagem Dois
Cada controlador de exibição especifica ganchos de subclasse ou API de configuração que permitirá que essas classes personalizadas de interface do usuário sejam definidas em tempo de execução (semelhante à forma como o UISplitViewController permite que os chamadores configurem os controladores usando a propriedade viewControllers). Para fazer isso, cada cliente simplesmente subclassifica o Controlador de Coordenação de base e em cada apresentação de controladores; defina os valores apropriados no controlador para que ele atinja a interface do usuário desejada. Algo como
viewController.registerReusableCellsBlock = ^(UICollectionView *collectionView){
//perform custom registration
}
viewController.cellDequeueBlock = ^UICollectionViewCell<SomeProtocol> *(UICollectionView *collectionView,NSIndexPath *indexPath){
//dequeue custom cells
}
Atualmente, separo a fonte de dados para uma exibição em um objeto separado para promover a reutilização e impedir o inchaço do ViewController. Isso torna a subclasse do controlador de exibição fornecer a interface das células um pouco mais difícil, mas não impossível.
Abordagem 3
Talvez seja uma má idéia tentar projetar uma estrutura e antecipar seu uso. Talvez a melhor opção seja permitir a subclasse com controle máximo, mesmo que o custo de instalação seja relativamente alto. Então, depois de construí-lo para vários clientes, posso observar os padrões que surgem e começar a otimização ao longo da rota.
Entendo como posso torná-lo personalizável interno à estrutura, o que estou enfrentando é como definir melhor uma interface que defina os possíveis pontos de personalização da estrutura pelo cliente.
TL; DR
A parte mais complicada da interface lida com uma exibição de coleção aninhada dentro das células de exibição de coleção. Isso permite paginação horizontal e rolagem vertical de células. Isso é obtido com uma fonte de dados que gerencia as células horizontais e configura a exibição de coleção de cada célula com uma nova fonte de dados.
Como alguém projetaria uma interface que permita que todas essas células sejam personalizáveis?