Есть ли способ объединить статические ячейки таблицы (статический контент) с динамическими ячейками таблицы (содержимое прототипа) с помощью раскадровки?
Объединение статического и прототипного содержимого в виде таблицы
Ответ 1
Я предлагаю вам рассматривать вашу таблицу как динамическую, но включать ячейки, которые вы всегда хотите вверху. В Раскадке разместите UITableViewController
и используйте динамическую таблицу. Добавьте в таблицу столько прототипов UITableViewCell
, сколько вам нужно. Скажем, по одному для ваших статических ячеек, и один для представления ячеек переменных.
В вашем классе UITableViewDataSource
:
#define NUMBER_OF_STATIC_CELLS 3
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.dynamicModel count] + NUMBER_OF_STATIC_CELLS;
}
и, тогда
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row < NUMBER_OF_STATIC_CELLS) {
// dequeue and configure my static cell for indexPath.row
NSString *cellIdentifier = ... // id for one of my static cells
} else {
// normal dynamic logic here
NSString *cellIdentifier = @"DynamicCellID"
// dequeue and configure for [self.myDynamicModel objectAtIndex:indexPath.row]
}
}
Ответ 2
У меня была проблема, хотя это был небольшой вариант. Я действительно хотел смешивать динамические и статические ячейки, но в разных группах. Значение группы 1 будет иметь только статические ячейки, а группа 2 будет иметь динамические ячейки.
Я выполнил это путем на самом деле жесткого кодирования значений статических ячеек (на основе их идентификаторов прототипов). Динамические разделы будут иметь нормальный динамически заполненный контент. Вот пример кода, если у кого-то другая проблема:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 1){
return @"Dynamic Cells";
}
if (section == 0){
return @"Static Cells";
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0) {
return 1; //However many static cells you want
} else {
return [_yourArray count];
}
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
if (indexPath.section == 0) {
NSString *cellIdentifier = @"staticCellType";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = @"some static content";
return cell;
} else if (indexPath.section == 1){
NSString *cellIdentifier = @"dynamicCellType";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [_yourArray objectAtIndex:indexPath.row];
return cell;
}
return nil;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
Ответ 3
К сожалению, это невозможно, так как представления static table должны находиться в UITableViewController и это разрешает только один вид таблицы.
Что вам нужно сделать, это сделать еще три динамических UITableviewCell и загрузить их по отдельности для первых трех строк, где вы хотите статический контент.
Если вы не знаете, как это сделать, дайте мне знать, и я могу найти код.
Ответ 4
Вы всегда можете сделать то, что ваши табличные представления похожи на статическую таблицу, но определяют ее в коде. Задайте разделы, количество или строки в каждом разделе, заголовки и т.д. С помощью методов делегата.
Ответ 5
Поскольку никто фактически не дал реального ответа на проблему (используя как статические, так и прототипные ячейки в одном и том же представлении таблицы), я решил, что буду звонить. Это можно сделать!
Создайте свои статические ячейки по своему усмотрению. Для разделов, которым нужна динамическая ячейка, если вы НЕ используете стандартный тип UITableViewCell, вам нужно создать свой собственный в отдельном Nib, иначе вы можете использовать стандартные. Затем выполните следующие делегаты. В основном для каждого из этих делегатов, для статического материала, который мы хотим назвать супер, для динамического мы возвращаем наши значения.
Сначала, если вам нужно выборочно показать свой динамический раздел, вы захотите реализовать numberOfSectionsInTableView (иначе вы можете оставить этот делегат):
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
int staticSections = 1;
int dynamicSections = 1;
if(SOME_BOOLEAN) {
return staticSections + dynamicSections;
}else {
return staticSections;
}
}
Затем вам нужно реализовать numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == 2) {
return A_COUNT;
}else {
return [super tableView:tableView numberOfRowsInSection:section];
}
}
Затем вам нужно реализовать heightForRowAtIndexPath:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 2) {
return 44.0f;
}else {
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
Затем indentationLevelForRowAtIndexPath:
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 2) {
return 1;
}else {
return [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath];
}
}
Наконец, cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 2) {
SomeObject *obj = self.someArray[indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"DynamicCell" forIndexPath:indexPath];
cell.textLabel.text = obj.textValue;
return cell;
}else {
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
}
Ответ 6
У вас нет одного статического представления таблицы, а другая динамика в том же контроллере просмотра, что вам нужно будет сделать их динамическими. В первом представлении таблицы вы настроите ячейки в коде при инициализации контроллера представления, никогда не обновляя их.
- Добавьте UIViewController в свою раскадровку.
- Добавить два вида таблицы (не TableViewControllers) в контроллер UIView.
- Выберите каждый tableView и настройте оба для динамических ячеек.
- Создайте и прикрепите контроллер вида. 2 tableview в одном представлении объясняет этот шаг.
В качестве другого варианта вы можете добиться аналогичного взгляда, вставив свой динамический табличный просмотр в часть вида, аналогичного ссылке на шаге 4, а затем сделайте все, что захотите, в остальной части представления, чтобы настроить то, что вы планировали делать со статическими ячейками с помощью scrollviews, меток и кнопок.
Ответ 7
Вы также можете создавать кнопки (по одному для каждой статической ячейки, которые у вас есть), которые стилизованы подобно вашим ячейкам, и помещают их в tableHeaderView или tableFooterView из UITableView; эти кнопки просто видны.
Вам нужно будет добавить некоторую логику для выбора на кнопках по сравнению с ячейками, чтобы поддерживать обычный внешний вид.
Конечно, это предполагает, что вы хотите вставить статические ячейки в свой вид таблицы вверху или внизу таблицы.
Ответ 8
Один из способов динамического содержимого в представлении статической таблицы - клонировать ячейки, где необходимы дополнительные строки.
В динамическом разделе моего представления таблицы я выложу одну или несколько ячеек в Interface Builder. Во время выполнения я могу клонировать их с помощью архивирования с использованием NSCoder, а затем с помощью unarchiving.
Он работает, но не обязательно красивее, чем начинать с представления таблицы динамического прототипа и создавать там статические строки.
Он не работает со стандартными ячейками таблицы. Ленько созданные текстовые метки не выложены правильно. Следовательно, я использовал подклассы UITableViewCell, где я занимаюсь архивированием и разборчиками.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == kContactsSection) {
NSArray *contacts = self.contacts;
Contact *contact = [contacts objectAtIndex:indexPath.row];
NSString *name = contact.name;
NSString *role = contact.role;
if ([role length] == 0) {
NNContactDefaultTableViewCell *cell = (id)[tableView dequeueReusableCellWithIdentifier : @"contactDefault"];
if (cell == nil) {
NNContactDefaultTableViewCell *template = (id)[super tableView : tableView
cellForRowAtIndexPath :[NSIndexPath indexPathForRow:0 inSection:kContactsSection]];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:template];
cell = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
cell.contactTextLabel.text = name;
return cell;
}
else {
NNContactDetailTableViewCell *cell = (id)[tableView dequeueReusableCellWithIdentifier : @"contactDetail"];
if (cell == nil) {
NNContactDetailTableViewCell *template = (id)[super tableView : tableView
cellForRowAtIndexPath :[NSIndexPath indexPathForRow:1 inSection:kContactsSection]];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:template];
cell = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
cell.contactTextLabel.text = name;
cell.contactDetailTextLabel.text = role;
return cell;
}
}
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
В приведенном выше примере у меня есть два типа ячеек. Оба изложены в интерфейсе Builder как часть статического представления таблицы.
Чтобы получить динамический контент в одном разделе, мне также необходимо переопределить следующие методы:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == kContactsSection) {
NSArray *contacts = self.contacts;
NSUInteger contactCount = [contacts count];
return contactCount;
}
return [super tableView:tableView numberOfRowsInSection:section];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger section = indexPath.section;
NSInteger row = indexPath.row;
if (section == kContactsSection) {
return [super tableView:tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:kContactsSection]];
}
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
- (CGFloat)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger section = indexPath.section;
if (section == kContactsSection) {
CGFloat indentation = [super tableView:tableView indentationLevelForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:kContactsSection]];
return indentation;
}
CGFloat indentation = [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath];
return indentation;
}