具有动态单元格高度

时间:2016-04-23 03:27:51

标签: ios uitableview xamarin xamarin.ios autolayout

我有一个动态的项目列表,每个项目可以有不同的teamplate / layout(和height)。其中一个项目类型可以有一个内部的项目列表供选择,定期5-6行,每行有不同的高度。

如果我尝试进一步描述它,在我的场景中,我在另一个tableview(#master)的tableviewcells(#master-cell)中有一个tableview(#slave)。此外,我的#slave tableview中的单元格(#slave-cell)也可能具有不同的高度。所以我需要布局我的#slave让#master自动计算并更新它的大小。

enter image description here

我遇到了内部表(#slave)的问题。在自动布局的情况下,为了适应所有单元格空间,表格将与UILabel或其他控件不同地折叠。所以我需要的是获得#slave表的预计大小并设置#slave的#slave =内容高度的高度。

我发现similar post如果所有行都具有相同的高度但是我使用动态高度的自定义行,那么tableView.contentSize.Height会给我无效的结果(基本上只是乘以rowNumbers * estimatedRowHeight,你可以在截图上看到它,主要项目#3有4个内部单元格)。即使在调用#slave.reloadData之后,我也无法达到那么大。

构建这种UI的正确方法是什么?

带有测试项目的

Source code(Xamarin.iOS)

8 个答案:

答案 0 :(得分:4)

我几天前遇到了同样的问题,并试图解决它。

#master-cell的工作方式类似于childViewController,它是#slave TableViewController的delegate datasource。但是你不能在UITableViewcell中拥有一个childViewController。

自定义UITableViewCell以保存必要的属性并充当#slave TableViewController的delegate datasource,并配置#slave-cell's 身高和数据。

真正的问题是#master-cell的高度,

  1. 如果您的数据是简单且静态的,您可以提前计算高度,并在ViewController的方法func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat中返回它。
  2. 否则,向#master-cell添加一个方法,该方法在设置其属性时返回整个单元格的高度。并创建一个代理#master-cell来计算高度并返回它:

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
      let cell   = CustomUITableViewCell();
      let model  = self.getModel(indexPath)
      cell.model = model
      let height = cell.requiredHeight()
      return height;
    }    
    

    它既复杂又昂贵,但它确实有效。

答案 1 :(得分:3)

我认为你不需要在UITableView内采取UITableView。您可以在UITableView中使用多个部分。并使用不同的cellReuseIdentifier。这样你的目标就会实现。

答案 2 :(得分:1)

对于这样的布局ios在tableview中提供了部分,对于主项目使用SectionView(有sectionView的委托方法 - >在其中你可以为一个部分提供视图),因为不同的部分可能有不同类型的行,所以make根据您的需要排列并按照部分返回。

答案 3 :(得分:1)

也许是因为我不知道你的项目背景或你想要完成什么,但tableVIew单元格中的tableViews听起来不必要的微不足道。而不是使用带有#slave tableViews的主tableView,只需在单个tableView中按部分分解,如前一个答案中所述。 UITableViewDelegate方法旨在为您精简这一点!

答案 4 :(得分:1)

首先你必须得到字符串的高度然后高度必须在tableView委托下面给出

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return stringHeight;

}

它对我有用。

答案 5 :(得分:1)

我正在使用Xcode 8.3.2和Swift3.1。

我有同样的要求,尝试了所有,没有任何对我有用。

最后,UIStackView对我有用。

在tableviewcell中,我添加了一个UIStackView(Verticle),继续向该UIStackView添加子单元格。它会自动增加细胞高度。

检查以下内容以编程方式添加UIStackView。

Add views in UIStackView programmatically

答案 6 :(得分:0)

如果您使用不同的部分和行使用以下格式,它适用于我,

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0) {
        return 121;
    }
    if(indexPath.section==1)
    {
        return 81;
    }

    if (indexPath.section%2 == 0 && indexPath.row == 1) {
        return 161;
    }

    if (indexPath.section%2 != 0 && indexPath.row == 0) {
        return 81;
    }

    if (indexPath.section==16 && indexPath.row==0) {
        return 161;
    }
    else
    {
        return 44;
    }
}

我有模板代码,不同的部分和行,它的每一行都有不同的大小,所以我给出了这种类型的代码,如果你有想法看到上面的代码那么它对你有帮助,

如果更改内容文字大小的高度,请使用下面的代码,它计算内容大小然后更改高度(UILabel)大小,它对我有用

-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ListModel *model = [ListArray objectAtIndex:indexPath.row];

    CGRect labelRect = [model.content boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 90 - 15, 0)
                        options:NSStringDrawingUsesLineFragmentOrigin
                        attributes:@{
                                     NSFontAttributeName : [UIFont fontWithName:@"Arial" size:14.0]
                                     }
                        context:nil];

    CGFloat heightOfCell = labelRect.size.height + 60;

    if(heightOfCell > 106)
        return heightOfCell;

    return 106;
}

希望它有用

答案 7 :(得分:-1)

是的,当然你可以拥有你想要的原型单元格,例如检查这段代码:

     override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        if indexPath.section == 0 {

        let cell =  tableView.dequeueReusableCellWithIdentifier("TodayWeatherCell", forIndexPath: indexPath) as! SITodayWeatherTableViewCell

        cell.setupCell(upCommingWeather)
        cell.aboutCityUpdateTableViewClousure = {
            self.tableView.reloadData()
        }

        return cell
    }else {

        let cell = tableView.dequeueReusableCellWithIdentifier("cityDetailCell", forIndexPath: indexPath) as! SICityDetailTableViewCell
        let detail = detailCity[indexPath.row]
        cell.setupCityDetail(detail)

        return cell
        // Configure the cell...
    }
  }

单个UITableView中有两个不同的单元格。

希望它有所帮助。