ios - 使用 AutoLayout 在不同高度的两列中堆叠

标签 ios uitableview xamarin.ios autolayout mvvmcross

针对 iOS 8.1

我正在使用 AutoLayout 在 TableCell 中布置多个标签。其中一些标签是可选的,有些可以包装它们的文本。它们分为两个“列”,这些列只是 TableCell 的 ContentView 中的两个 UIView。我的约束以编程方式应用。

第二次更新

没有SwiftArchitect's answer下面我不会解决这个问题并接受他的回答。但是因为我的都是代码,在自定义表格单元格中,我还添加了一个 separate answer below

更新

为了阻止标签拉伸(stretch)到比所需尺寸更大的尺寸,我之前将 SetContentHuggingPrioritySetContentCompressionResistancePriority 设置为 1000,因为我相信这是相当于说“我希望 Label 将其内容紧贴到它的确切高度,我不希望它被垂直压缩” 正如您在下面的红色和粉红色示例中所见,AutoLayout 显然没有遵守此请求。

this.notesLabel.SetContentHuggingPriority(1000, UILayoutConstraintAxis.Vertical);
this.notesLabel.SetContentCompressionResistancePriority(1000, UILayoutConstraintAxis.Vertical);

我删除了这些优先级的设置,标签不再被压扁,这是我原来的问题。当然,现在某些标签被拉伸(stretch)超出了它们需要的高度。

  1. 为什么删除 Hugging 和 Compression 优先级会修复我的问题 问题?
  2. 如何在不返回上一期的情况下让红色框中的文本(红色框不是后来添加的单元格的一部分)不展开?

enter image description here

以下是设置压缩和拥抱优先级后的一些截图。背景颜色用于调试

enter image description here

普遍的问题是包含 View (紫色和红色)将自身调整为两者中较小的一个。正如您在顶部看到的那样,“优先级 3”正在被删除,因为左列容器不需要更高。

在下一个示例中,没有优先级标签,但 EventDate 被压缩了。

enter image description here

最佳答案

已编写并测试了以下答案。它适用于 iPhone 和 iPad,纵向和横向。最高的一列获胜,另一列只占据它需要的空间。如果需要,它甚至可以修改为垂直居中对象。它解决了垂直裁剪标签问题以及动态缩放问题。

enter image description here

初步建议

  • 如果可以,请使用 Storyboard。您可以使用最先进的 GUI 直观地测试所有约束。
  • 不要修改拥抱、压缩,甚至 UILabel 高度:让每个标签在垂直方向占据它需要的空间,并且只添加顶部和侧面 anchor
  • 使用额外的 View 作为容器来定义每列的宽度。使用 multiplier 得到,比如说三分之二和三分之一。
  • 通过向最低标签的底部添加单个高度约束(leftColumn.bottom Equal lowestLeftLabel.bottom),让这些 View 计算它们的理想高度
  • 不要动态添加或删除 View ;相反,隐藏它们以便它们保留关联的约束。

解决方案说明

为简单起见,我创建了 2 个 subview ,每列 1 个,并将它们并排放置。它们锚定在上/左和上/右,它们的宽度是计算出来的,它们的高度是从它们各自的内容(*)中得出的。

左右 subview 有一个 1/2 的 multiplier,我在其中添加了一个 2 像素的 constant 作为边距。这两列内的标签左右锚定(leading space 到容器,trailing space 到容器),边距为 8 像素。这确保没有标签会超出其列。

  1. 请考虑您的 UITableViewCell 的高度是 2 个内部列中最大的。换句话说,containerView.height >= left.height containerView.height >= right.height。
  2. 确保您没有删除任何不可见的标签。 view.hidden 不会破坏您的约束,这就是您想要的。
  3. 将每个 UILabel 左右锚定到容器,最上面的也锚定到容器,但是每个后续的 label.top 都应该锚定到上面的 .bottom它。这样,您的内容就会流动。如果需要,您可以添加边距。

(*) 最后的关键是将每列的高度与该列的约束联系起来,使其等于该列最低标签的 .bottom。在上面的示例中,您可以清楚地看到蓝色背景的右侧栏比左侧栏短。

enter image description here

虽然我看到您想要一个代码解决方案,但我在不到 15 分钟的时间内使用 Storyboard 创建了我的示例。它不仅仅是一个概念,它是一个实际的实现。它只有 0 行代码,并且适用于所有 iOS 设备。顺便说一句,它也有 0 个错误

所有约束列表

注意 >= 散布在各处。它们是让您的柱子独立高大的关键。

对于 LRNSLayoutContraint 实际上是相同的。

enter image description here

enter image description here

获取 Storyboard here , 和一篇详细的文章 there .

关于ios - 使用 AutoLayout 在不同高度的两列中堆叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31658526/

相关文章:

ios - 如何在 iOS 中的 soap 请求后刷新 tableview

swift - 当用户在单元格中键入内容时,使 UITableView 标题自动调整大小

ios:是否有一个函数在您更改合适的部分时调用?

ios - 未经用户确认的 USSD 调用

ios - 符合关联类型协议(protocol)的对象的 Swift 集合

c# - MonoTouch.Dialog 仅图像单元格

xamarin - 如何在 iOS 16 中更改方向?

ios - 未为自定义 UITableViewCell 调用 GetHeightForRow

android - React Native MapView 使用相机标题旋转 map

ios - iphone App 中字符串的幻灯片放映