Mam za zadanie zaprojektować platformę aplikacji, która pozwoli każdej implementacji dostosować części interfejsu użytkownika. Jednym z takich przykładów może być to, że implementacja (od tej pory nazywamy ją klientem) może zdefiniować komórki widoku kolekcji, aby powrócić do określonego ekranu. Ramy są po prostu odpowiedzialne za vending odpowiednich obiektów, aby ułatwić tworzenie aplikacji, ponieważ będziemy budować kilka podobnych wyglądających instancji.
Moje obecne podejście do tej struktury polega na zaprojektowaniu Kontrolera Koordynacji, który byłby odpowiedzialny za wszystkie prezentacje i odwołania w całej aplikacji. Domyślny kontroler koordynacji rozdziela wszystkie domyślne kontrolery widoku wewnątrz frameworka, które wszystkie wykonują swoje odpowiednie zadania, niekoniecznie zapewniając skonfigurowany interfejs użytkownika. Na przykład: jeden kontroler pokaże widok kolekcji z komórkami szablonu i niczym specjalnym. Zaletą tego projektu jest to, że usuwa on sprzężenie między kontrolerami, a także pozwala klientowi zastąpić domyślnego koordynatora i zwrócić całkowicie nowy kontroler widoku dla określonego zadania.
Mam problem z tym, jak zaprojektować tę platformę, aby umożliwić klientowi dodanie własnego niestandardowego interfejsu użytkownika do aplikacji.
Podejdź do pierwszego
Spraw, aby środowisko wymagało fabryki widoków, i niech ta fabryka widoków będzie odpowiedzialna za usunięcie wszystkich odpowiednich widoków. W związku z tym w aplikacji delegowanej możemy wymusić na przykład, aby klient utworzył CollectionViewCellFactory, a interfejs definiuje wszystkie komórki, które każda zgodna klasa będzie musiała podać. Odziedziczyłem bazę kodu z tym projektem i zrezygnowałem z niego, ponieważ był on zbyt abstrakcyjny i można go dostosować. Dostarczono z mnóstwem fabryk dla każdego aspektu aplikacji, a to dodało dni do czasu konfiguracji każdej aplikacji.
Podejdź dwa
Każdy kontroler widoku określa przechwyty podklasy lub konfiguracyjny interfejs API, który pozwoli na zdefiniowanie tych niestandardowych klas interfejsu użytkownika w czasie wykonywania (podobnie do tego, w jaki sposób UISplitViewController umożliwia dzwoniącym konfigurowanie kontrolerów za pomocą właściwości viewControllers). W tym celu każdy klient po prostu podklasuje podstawowy kontroler koordynacji i prezentację w każdym kontrolerze; ustaw odpowiednie wartości na kontrolerze, aby osiągnął pożądany interfejs użytkownika. Coś jak
viewController.registerReusableCellsBlock = ^(UICollectionView *collectionView){
//perform custom registration
}
viewController.cellDequeueBlock = ^UICollectionViewCell<SomeProtocol> *(UICollectionView *collectionView,NSIndexPath *indexPath){
//dequeue custom cells
}
Obecnie dzielę źródło danych dla widoku na osobny obiekt, aby ułatwić ponowne użycie i zapobiec wzdęciom ViewController. To sprawia, że podklasowanie kontrolera widoku w celu zapewnienia interfejsu komórek jest nieco trudniejsze, ale nie niemożliwe.
Podejście 3
Być może złym pomysłem jest próba zaprojektowania frameworka i przewidywania jego użycia. Być może najlepszą opcją jest dopuszczenie podklasy z maksymalną kontrolą, nawet jeśli koszt konfiguracji jest stosunkowo wysoki. Następnie, gdy zbuduję go dla kilku klientów, mogę zauważyć pojawiające się wzorce i rozpocząć optymalizację na trasie.
Rozumiem, w jaki sposób mogę uczynić go dostosowywalnym wewnętrznie do frameworka, z czym zmagam się, jak najlepiej zdefiniować interfejs, który definiuje potencjalne punkty dostosowywania frameworka przez klienta.
TL; DR
Najbardziej skomplikowana część interfejsu dotyczy widoku kolekcji zagnieżdżonego w komórkach widoku kolekcji. Umożliwia to stronicowanie w poziomie i przewijanie w pionie komórek. Osiąga się to poprzez posiadanie jednego źródła danych, które zarządza poziomymi komórkami i konfiguruje widok kolekcji każdej komórki z nowym źródłem danych.
Jak zaprojektować interfejs, który umożliwia dostosowanie wszystkich tych komórek?