2017-01-20 5 views
0

Я перестраиваю приложение, где мне нужно показать список элементов. Этот список извлекается с использованием API или извлекается из Core Data и отображается в UITableViewController. Проблема, с которой я сталкиваюсь, состоит в том, что существует уже семь разных списков, где есть небольшие различия. В основном из них только разные элементы, но также строка поиска, включенная в один список, и ранее указанный один список не загружается с использованием API, а из Core Data.Reuse Storyboard viewcontrollers

В моей раскадровке я добавил UITableViewController с классом ItemsTableViewController, который имеет разработанный UITableViewCell. Я добавил идентификатор этой ячейки, чтобы я мог повторно использовать его внутри этого контроллера представления. На этом контроллере просмотра есть главный выход из главного экрана.

Идея состояла в том, чтобы создать один родительский объект (ItemsTableViewController) и добавить несколько дочерних объектов (SavedItemsTableViewController, LocalItemsTableViewController и т. Д.), Которые будут использовать общую логику родителя с небольшими изменениями (API и некоторые пользовательские вещи) ,

То, что я в настоящее время уже работает, но без дочерних объектов:

- (void)offlineButtonPressed { 
    [self performSegueWithIdentifier:@"openItemsTableViewController" sender:@(ItemListOffline)]; 
    //[[self navigationController] pushViewController:[[OfflineItemsTableViewController alloc] init] animated:YES]; 
} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([[segue identifier] isEqualToString:@"openItemsTableViewController"]) { 
     switch((ItemList)[sender unsignedIntegerValue]) { 
      case ItemListOffline: { [(ItemsTableViewController *)[segue destinationViewController] retrieveOfflineDocuments]; break; } 
      case ItemListSearch: { 
       [(ItemsTableViewController *)[segue destinationViewController] retrieveDocumentsWithQuery:@""]; 
       [(ItemsTableViewController *)[segue destinationViewController] addSearchBar]; 
       break; 
      } 
      // Loop through all the list... 
      default: { NSAssert(NO, @"Unhandled type of document list."); break; } 
     } 
    } 
} 

Так приложение вызова только функцию родительского объекта, который обрабатывает запрос. Но, как вы, вероятно, чувствуете, объект будет менее ремонтопригодным. В комментариях я нажал контроллер дочернего представления, но поскольку он не включает представление раскадровки, мне нужно воссоздать ячейку с нуля, что не очень хорошо. Плюс, так как идентификатор повторного использования, он не работает, поскольку он не может деактивировать ячейку с идентификатором, установленным в методе tableView: cellForRowAtIndexPath :.

Теперь мне интересно, какая была бы лучшая практика для этого? Кажется, я не могу использовать сохранение UITableViewController из раскадровки для нескольких дочерних классов, не так ли? Но создание семи (и, вероятно, еще большего в будущем) контроллеров в раскадровке, где мне нужно скопировать ячейки в каждый контроллер и просто дать им разные классы, похоже, не способ сделать это. И добавьте метод к родительскому объекту, где список будет получен по-разному, и смените некоторые вещи, такие как добавление строки поиска, но также и не самый приятный способ.

Обновление: логика в ItemsTableViewController довольно проста. В делегате и источнике данных я обрабатываю документы почти одинаково. Метод, который делает извлечение каждого типа списка есть что-то вроде:

- (void)retrieveOfflineItems { 
    [self startLoading]; 

    [[APIManager instance] getOfflineItems:^(NSArray<ItemList *> *list, NSError *error) { 
     [self setDocuments:list]; 
     [[self tableView] reloadData]; 
    }]; 
} 

Но есть еще вещи, как поиск должен добавить строку поиска (после загрузки вида). Поэтому при выполнении сеанса необходимо вызвать несколько методов.

ответ

1

Вы можете иметь один UITableViewController, который включает в себя все ваших возможных ячейках таблицы, а также как часть prepareForSegue вызова, вы должны установить идентификатор типа контроллера и данные - независимо от того, где данные пришли из ,

В классе UITableViewController вы можете скрыть/отобразить функции, необходимые для этого типа данных - например, панель поиска и методы tableView, выберите источник данных, который вам нужен.

Таким образом, один класс UITableViewController, который вам нужно поддерживать, немного сложнее, чем один выделенный класс, но гораздо удобнее, чем 7 или более!

Предполагая, что вы создали переменную DATATYPE для определения типа данных, которые необходимо, вы могли бы что-то подобное для numberOfRowsInSection, а затем аналогично для других методов Tableview

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
{ 
    switch self.dataType { 
    case dataType.MyFirstDataType: 
     return myFirstDataTypeArray.count 

    case dataType.MySecondDataType: 
     return mySecondDataTypeArray.count 

    case dataType.TheCoreDataType: 
     return myCoreDataArray.count 

    default: 
     break 
    } 
} 
+0

Спасибо за комментарий. Я обновил вопрос, источник данных и делегат идентичны и будут использоваться от родителя в любом случае. Это в основном другой список элементов, которые я получаю, и некоторые изменения графического интерфейса. Таким образом, viewDidLoad может немного отличаться, поскольку панель поиска должна быть добавлена ​​в один список, и список будет извлекаться с использованием другого метода из APIManager. – Sietse

0

Создание родительского UITableViewController со всеми подзонами и ячейками, включая searchController. Инициализировать его и добавить/удалить представления и ячейки на основе условий

Смежные вопросы