在表视图中组合静态和原型内容

时间:2012-02-17 04:25:57

标签: iphone ios uitableview storyboard

有没有办法使用故事板将静态tableview单元格(静态内容)与动态tableview单元格(原型内容)结合起来?

8 个答案:

答案 0 :(得分:55)

我建议你把你的桌子视为动态,但是在顶部包含你总是想要的细胞。在故事板中,放置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]
    }
}

答案 1 :(得分:12)

我有一个问题,虽然这是一个轻微的变种。我实际上想要混合动态和静态细胞,但是在不同的组中。意义组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;
}

答案 2 :(得分:5)

由于没有人真正提供问题的真实答案(在同一个表格视图中同时使用静态和原型单元格),我想我会加入。 它可以做到!

根据需要创建静态单元格。 对于需要动态单元格的部分,如果您不使用标准的UITableViewCell类型,则需要在单独的Nib中创建自定义的部分,否则可以使用标准的Nib。 然后实现以下代理。基本上对于每个代表,对于我们想要调用super的静态东西,对于动态,我们返回我们的值。

首先,如果您需要有选择地显示您的动态部分,您将要实现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 == 1) {
        return A_COUNT;
    } else {
        return [super tableView:tableView numberOfRowsInSection:section];
    }
}

然后,您需要实现heightForRowAtIndexPath:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 1) {
        return 44.0f;
    } else {
        return [super tableView:tableView heightForRowAtIndexPath:indexPath];
    }
}

然后是indentationLevelForRowAtIndexPath:

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 1) {
        return 1; // or manually set in IB (Storyboard)
    } else {
        return [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath]; // or 0
    }
}

最后,cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 1) {
        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];
    }
}

答案 3 :(得分:3)

不幸的是,这是不可能的,因为静态表视图必须在UITableViewController中并且只允许一个tableview。

你需要做的是制作三个更加动态的UITableviewCell,并为你想要静态内容的前三行分别加载它们。

如果您不确定如何操作,请告诉我,我可以找到一些代码。

答案 4 :(得分:3)

您可以随时创建一个表格视图与静态表格类似,但在代码中定义它。通过委托方法设置每个部分,标题等的部分,数量或行。

答案 5 :(得分:2)

在同一个视图控制器中,您不能将一个tableview设置为静态而另一个是动态的,因此您需要使它们都是动态的。在第一个tableview中,您将在初始化视图控制器时在代码中配置单元格,从不更新它们。

  1. 将UIViewController添加到故事板。
  2. 添加两个表视图(不是 TableViewControllers)到UIView控制器。
  3. 选择每个tableView并为动态单元格配置它们。
  4. 构建并附加视图控制器。 2 tableview on a single view解释了这一步。
  5. 作为另一个选项,您可以通过将动态tableview嵌入类似于步骤4中的链接的视图的一部分来实现类似的外观,然后在视图的其余部分中执行您想要的任何操作来设置您计划执行的操作使用滚动视图,标签和按钮使用静态单元格。

答案 6 :(得分:0)

您还可以创建与单元格类似的按钮(每个静态单元格一个),并将它们放在UITableView的tableHeaderView或tableFooterView中;毕竟这些按钮只是视图。

您需要添加一些逻辑来对按钮和单元格进行选择,以便保持通常的外观。

当然,这假设您要将静态单元格插入表格顶部或底部的表格视图中。

答案 7 :(得分:0)

在静态表视图中使用动态内容的一种方法是克隆需要其他行的单元格。

对于表视图的动态部分,我在Interface Builder中布置了一个或多个单元格。在运行时,我可以通过使用NSCoder归档然后取消归档来克隆它们。

它可以工作,但不一定比从动态原型表视图开始并从那里创建静态行更漂亮。

标准表视图单元格失败。懒惰创建的文本标签未正确布局。因此,我使用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];
}

在上面的例子中,我有两种细胞类型。两者都在Interface 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;
}