Xamarin.iOS 中的自动调整行高度

警告

iOS Designer 在 Visual Studio 2019 版本 16.8 和 Visual Studio 2019 for Mac 版本 8.8 中已经弃用,并且已从 Visual Studio 2019 版本 16.9 和 Visual Studio for Mac 版本 8.9 中移除。 要生成 iOS 用户界面,建议直接在运行 Xcode 的 Interface Builder 的 Mac 上操作。 有关详细信息,请参阅用 Xcode 设计用户界面

从 iOS 8 开始,Apple 新增了创建表视图 (UITableView) 的功能,该视图可使用“自动布局”、“大小类别”和“约束”,根据内容的大小自动增大或缩小给定行的高度。

iOS 11 增加了行自动展开的功能。 现在可以根据内容自动调整页眉、页脚和单元格的大小。 但是,如果表是在 iOS 设计器、Interface Builder 中创建的,或者表的行高是固定的,必须按照本指南的描述,手动启用单元格的自动大小调整。

iOS 设计器中的单元格布局

在 iOS 设计器中打开要自动调整行大小的表视图的情节提要,选择单元格的“原型”并设计单元格的布局。 例如:

单元格的原型设计

为原型中的每个元素添加约束,使元素在表视图因旋转或不同 iOS 设备屏幕尺寸而调整大小时保持正确位置。 例如,将 Title 固定在单元格的“内容视图”的顶部、左侧和右侧:

将标题固定到单元格内容视图的顶部、左侧和右侧

在示例表中,小 Label(位于 Title 下方)是可以收缩和增大以增加或减少行高度的字段。 为了达到这种效果,添加以下约束,以固定标签的左边、右边、顶部和底部:

这些限制用于固定标签的左侧、右侧、顶部和底部

现在我们已经完全限制了单元格中的元素,我们需要明确哪些元素应该被拉伸。 为此,请根据需要在 Properties Pad 的“布局”部分设置“内容吸附优先级”和“内容压缩阻力优先级”

Properties Pad 的“布局”部分

将希望展开的元素设置为具有较低的吸附优先级值和较低的压缩阻力优先级值

接下来,我们需要选择单元格原型,并给它一个唯一标识符

为单元格原型提供唯一标识符

在本示例中,GrowCell。 稍后在填充表时,我们将使用此值。

重要

如果表中包含不止一种单元格类型(原型),则需要确保每种类型都有自己唯一的 Identifier,以便自动调整行大小。

为单元格原型的每个元素分配一个名称,以将其公开给 C# 代码。 例如:

分配名称以将其公开给 C# 代码

接下来,为 UITableViewControllerUITableViewUITableCell(原型)添加自定义类。 例如:

为 UITableViewController、UITableView 和 UITableCell 添加自定义类

最后,为了确保所有预期的内容都在标签中显示,请将 Lines 属性设置为 0

Lines 属性设置为 0

定义 UI 后,让我们添加代码以启用自动行高度大小调整。

启用自动调整高度大小

在表视图的数据源 (UITableViewDatasource) 或源 (UITableViewSource) 中,当我们对一个单元格取消排队时,需要使用我们在设计器中定义的 Identifier。 例如:

public string CellID {
    get { return "GrowCell"; }
}
...

public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath)
{
    var cell = tableView.DequeueReusableCell (CellID, indexPath) as GrowRowTableCell;
    var item = Items [indexPath.Row];

    // Setup
    cell.Image = UIImage.FromFile(item.ImageName);
    cell.Title = item.Title;
    cell.Description = item.Description;

    return cell;
}

默认情况下,表视图将设置为“自动调整行高”。 若要确保这一点,应将 RowHeight 属性设置为 UITableView.AutomaticDimension。 我们还需要在 UITableViewController 中设置 EstimatedRowHeight 属性。 例如:

public override void ViewWillAppear (bool animated)
{
    base.ViewWillAppear (animated);

    // Initialize table
    TableView.DataSource = new GrowRowTableDataSource(this);
    TableView.Delegate = new GrowRowTableDelegate (this);
    TableView.RowHeight = UITableView.AutomaticDimension;
    TableView.EstimatedRowHeight = 40f;
    TableView.ReloadData ();
}

这个估计值不一定要精确,只需粗略估计表视图中每个行的平均高度即可。

有了此代码,当应用运行时,每一行都会根据单元格原型中最后一个标签的高度缩小或增大。 例如:

示例表运行