Мені доручено розробити рамку програми, яка дозволить кожній реалізації налаштувати частини користувальницького інтерфейсу. Одним з таких прикладів може бути те, що реалізація (давайте назвемо її клієнтом відтепер) може визначати комірки подання колекції для повернення на певний екран. Рамка просто відповідає за продаж відповідних об'єктів, щоб зробити програму набагато простішою, оскільки ми будуватимемо декілька подібних схожих екземплярів.
Мій сучасний підхід до цієї рамки полягає в розробці контролера координації, який відповідає за всі події презентації та звільнення у програмі. Контролер координації за замовчуванням розповсюджує всі контролери перегляду за замовчуванням у рамках, які всі виконують відповідні завдання, не обов'язково надаючи налаштований інтерфейс користувача. Наприклад: один контролер покаже подання колекції з шаблонами комірок і нічого особливого. Перевага цієї конструкції полягає в тому, що вона видаляє з'єднання між контролерами, а також дозволяє клієнтові замінити координатора за замовчуванням і повернути абсолютно новий контролер перегляду для конкретного завдання.
Проблема, яку я маю, полягає в тому, як я повинен розробити цю рамку, щоб дозволити клієнту додавати власний користувальницький інтерфейс у додаток.
Підхід один
Зробіть так, щоб рамка вимагала фабрики перегляду, і нехай ця фабрика подання відповідає за розпродаж усіх відповідних представлень. Таким чином, в Делегат додатків ми можемо примусити клієнт створити CollectionViewCellFactory, наприклад, і інтерфейс визначає всі комірки, які потребує будь-який відповідний клас. Я успадкував базу коду з цим дизайном і віддалився від нього, оскільки він був занадто абстрактним і настроюваним. Він поставляється з безліччю фабрик для кожного аспекту програми, і це додало днів на час налаштування кожного додатка.
Підхід два
Кожен контролер перегляду вказує гачки підкласифікації або API налаштування, які дозволять визначати ці користувацькі класи інтерфейсу користувача під час виконання (подібно до того, як UISplitViewController дозволяє абонентам встановлювати контролери за допомогою властивості viewControllers). Для цього кожен клієнт просто підкласирує базовий контролер координації та в кожній презентації контролерів; встановіть відповідні значення на контролер, щоб він досяг бажаного інтерфейсу. Щось на зразок
viewController.registerReusableCellsBlock = ^(UICollectionView *collectionView){
//perform custom registration
}
viewController.cellDequeueBlock = ^UICollectionViewCell<SomeProtocol> *(UICollectionView *collectionView,NSIndexPath *indexPath){
//dequeue custom cells
}
В даний час я відокремлюю джерело даних для подання на окремий об'єкт, щоб сприяти повторному використанню та запобігання здуття ViewController. Це робить підкласифікацію контролера перегляду подавати інтерфейс комірок трохи складніше, але не неможливо.
Підхід 3
Можливо, погана ідея намагатися розробити рамки та передбачити її використання. Можливо, найкращий варіант - це допускати підкласи з максимальним контролем, навіть якщо вартість налаштування відносно висока. Потім, як тільки я побудував це для кількох клієнтів, я міг би помітити закономірності, які з’являються, і почати оптимізацію на маршруті.
Я розумію, як я можу зробити його настроюваним внутрішнім для фреймворку, з чим я борюся - це як найкраще визначити інтерфейс, який визначає потенційні точки настройки рамки клієнтом.
TL; DR
Найскладніша частина інтерфейсу стосується перегляду колекції, вкладеного всередину осередків перегляду колекції. Це дозволяє здійснити горизонтальну підкачку та вертикальну прокрутку клітин. Це досягається наявністю одного джерела даних, який управляє горизонтальними осередками та налаштовує вигляд колекції кожної комірки з новим джерелом даних.
Як можна створити інтерфейс, який дозволяє налаштувати всі ці комірки?