自调整大小 UITableViewCell 内的多个 UILabel

2024-01-10

在我正在创建的这个 iOS 8 应用程序中,我有一个表格视图,我需要它们自动调整大小。我使用自动布局实现了它并且它有效。几乎。现在看起来是这样的。

单元格内有 3 个标签。具有 lorem ipsum 文本的主标签。具有数字字符串的副标题(这是两个单独的标签。可能会令人困惑,因为它们具有相同的颜色。)然后是第三个带有黑色小文本的标签。

第一个标签正确调整了自身大小,没有任何问题,第二个标签相应地上下移动。但问题出在第三个小标签上。正如您所看到的,它没有调整自身大小以适应所有文本。

现在发生了一件奇怪的事情。我将其横向旋转,这就是它。

由于存在空间,标签将显示其应有的整个文本。美好的。然后我把它转回肖像。

现在,小标签已调整自身大小以适合其所有文本,但它溢出了单元格边界。我尝试将单元变大,但没有成功。由于这是自我调整大小的单元格,我认为这甚至不是正确的方法。

我也没有收到任何错误,甚至没有关于我的自动布局约束的警告。

我已将这两行代码设置在viewDidLoad() method.

tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension

谁能告诉我我在这里可能做错了什么?

由于仅通过查看图像很难回答,并且除了上面的代码片段之外我没有更多代码可发布,因此我上传了一个可运行的 Xcode 项目来演示该问题here https://www.dropbox.com/s/t3zslfl77s54zga/Layout.zip?dl=0。 (有 2 个自定义单元格。基本上是相同的单元格,只是第二个单元格的高度增加了。)

我一直在摆弄自动布局约束,但我似乎无法让它工作。任何帮助,将不胜感激。

谢谢。


UPDATE:

借助这个tutorial http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout我找到了一些有用的指示。根据它,每个子视图应该有固定其所有侧面的约束,并且应该有从上到下的约束,这有助于自动布局计算单元格的高度。在我原来的帖子中,每个标签之间都有垂直空间,所以我认为这就是自动布局无法计算正确高度的原因。

所以我做了一些改变。

  • 我将标签之间的垂直空间减少到 0,并设置顶部和中间标签以及中间和底部标签之间的垂直空间约束。
  • 我向顶部标签添加了前导、顶部、尾随约束。
  • 前导和尾随到中间标签。
  • 前导、底部、尾随到底部标签。

现在还有另一个奇怪的部分。当我第一次运行它时,底部标签裁剪问题仍然存在。

但是,如果我将设备旋转为横向并将其转回纵向,则所有单元格都会正确调整大小以适合两个标签!

但仍然不明白为什么这种情况一开始不会发生。更新的 Xcode 项目是here https://www.dropbox.com/s/vfdzlpadaetlek4/SelfSizingCellsIssue.zip?dl=0.


这里的问题是多行标签'preferredMaxLayoutWidth财产。该属性告诉标签何时应该自动换行。必须正确设置每个标签的顺序intrinsicContentSize具有正确的高度,这最终是自动布局将用来确定单元格高度的。

Xcode 6 Interface Builder 引入了一个新选项,可以将此属性设置为自动的。不幸的是,存在一些严重的错误(从 Xcode 6.2/iOS 8.2 开始),从笔尖或 Storyboard 加载单元格时,无法正确/自动设置该错误。

为了解决这个错误,我们需要preferredMaxLayoutWidth设置为恰好等于标签在表视图中显示后的最终宽度。实际上,我们希望在从以下位置返回单元格之前执行以下操作tableView:cellForRowAtIndexPath::

cell.nameLabel.preferredMaxLayoutWidth = CGRectGetWidth(cell.nameLabel.frame)
cell.idLabel.preferredMaxLayoutWidth = CGRectGetWidth(cell.idLabel.frame)
cell.actionsLabel.preferredMaxLayoutWidth = CGRectGetWidth(cell.actionsLabel.frame)

仅仅添加这段代码是行不通的,因为当这3行代码执行时tableView:cellForRowAtIndexPath:,我们使用每个标签的宽度来设置preferredMaxLayoutWidth-- 但是,如果您此时检查标签的宽度,则会发现标签宽度与显示单元格并布置其子视图后的宽度完全不同。

此时我们如何使标签宽度准确,以便它们反映最终宽度?这是将所有内容组合在一起的代码:

// Inside of tableView:cellForRowAtIndexPath:, after dequeueing the cell

cell.bounds = CGRect(x: 0, y: 0, width: CGRectGetWidth(tableView.bounds), height: 99999)
cell.contentView.bounds = cell.bounds
cell.layoutIfNeeded()

cell.nameLabel.preferredMaxLayoutWidth = CGRectGetWidth(cell.nameLabel.frame)
cell.idLabel.preferredMaxLayoutWidth = CGRectGetWidth(cell.idLabel.frame)
cell.actionsLabel.preferredMaxLayoutWidth = CGRectGetWidth(cell.actionsLabel.frame)

好吧,那我们在这里做什么?嗯,您会注意到添加了 3 行新代码。首先,我们需要设置此表视图单元格的宽度,使其与表视图的实际宽度相匹配(假设表视图已经布局并具有其最终宽度,这应该是这种情况)。我们实际上只是尽早使单元格宽度正确,因为表视图最终将执行此操作。

您还会注意到我们正在使用99999对于高度。那是关于什么的?这是针对详细讨论的问题的简单解决方法here https://github.com/smileyborg/TableViewCellWithAutoLayout/issues/16,如果您的约束需要比单元格 contentView 的当前高度更多的垂直空间,您会得到一个约束异常,该异常实际上并不表示任何真正的问题。此时单元格或其任何子视图的高度实际上并不重要,因为我们只关心获取每个标签的最终宽度。

接下来,我们通过将 contentView 的边界设置为等于单元格的边界,确保单元格的 contentView 的大小与我们刚刚分配给单元格本身的大小相同。这是必要的,因为您创建的所有自动布局约束都是相对于 contentView 的,因此 contentView 必须具有正确的大小才能正确解决它们。只需手动设置单元格的大小即可not自动调整 contentView 的大小以匹配。

最后,我们在单元格上强制执行布局传递,这将使自动布局引擎解决您的约束并更新所有子视图的框架。由于单元格和内容视图现在具有与表视图中运行时相同的宽度,因此标签宽度也将是正确的,这意味着preferredMaxLayoutWidth对每个标签的设置将是准确的,并将导致标签在正确的时间换行,这当然意味着当在表视图中使用单元格时,标签的高度将被正确设置!

这绝对是 Apple 在 UIKit 中的一个错误,我们现在必须解决这个问题(所以请这样做提交错误报告 https://bugreport.apple.com与 Apple 合作,因此他们优先修复!)。

最后一点:如果您的表视图单元格contentViewwidth 不会扩展表视图的整个宽度,例如当右侧显示部分索引时。在这种情况下,您需要确保在设置单元格的宽度时手动考虑到这一点 - 您可能需要对这些值进行硬编码,例如:

let cellWidth = CGRectGetWidth(tableView.bounds) - kTableViewSectionIndexWidth
cell.bounds = CGRect(x: 0, y: 0, width: cellWidth, height: 99999)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自调整大小 UITableViewCell 内的多个 UILabel 的相关文章

  • iOS WKWebView 处理文件下载

    我面临以下问题 在 Web 界面中 文件下载是通过锚标记触发的 如下所示 a href bla blabla a 虽然 Safari 浏览器可以处理此请求并打开一个对话框来处理文件 但 WKWebView 将此视为普通链接并且不对其执行任何
  • 在回调函数中调用目标c函数

    如何在回调函数中调用目标c函数 回调函数 static OSStatus inputRenderCallback void inRefCon AudioUnitRenderActionFlags ioActionFlags const Au
  • 如何在应用程序项目中使用 Cocoa Touch 框架

    我熟悉构建单个 iOS 应用程序 但我坚持使用 Cocoa Touch 框架向多个应用程序共享通用代码 问题 框架的头文件不可见 无法链接到消费应用程序项目 我做了什么 1 我创建了一个名为 libTestFramework 的项目 Coc
  • 如何在 Swift 中使用 CoreBluetooth 更新 BLE 设备的电池电量?

    func peripheral peripheral CBPeripheral didDiscoverCharacteristicsFor service CBService error Error for c in service cha
  • iPhone SQLite页面缓存不断增长

    I use sqlite数据库用于存储 还有许多数据库事务 我的问题是 sqlite 页面缓存的内存使用量快速增长 在instruments我可以找到这条线 Graph Category Live Bytes Living Transien
  • 如何使用 SwiftUI 获取多个屏幕上的键盘高度并移动按钮

    以下代码获取键盘显示时的键盘高度 并将按钮移动键盘高度 在转换源 ContentView 和转换目标 SecibdContentView 处以相同的方式执行此移动 但按钮在转换目标处不移动 如何使按钮在多个屏幕上移动相同 import Sw
  • 在 UITextView 中获取 HTML

    我在中显示htmlUITextView by self textView setValue b Content b forKey contentToHTMLString 编辑内容后UITextView 我想获取包含 html 的内容 所以我
  • 删除分组 UITableView 中的分隔符

    我需要使用自定义单元格创建分组表格视图 每个单元格必须有一个背景图像 以便一个单元格的图像会接触第二个单元格的图像 依此类推 我尝试将分隔符样式设置为 无 但我仍然得到单元格之间的透明分隔符 请帮我删除单元格之间的空间 祝你有美好的一天 谢
  • 带约束的嵌套集合视图的意外行为 (Swift 4)

    我的表格视图中有一个单元格 其中包含水平分页集合视图 该集合视图的每个页面内都有一个垂直集合视图 为了避免 滚动滚动 问题 我在垂直集合视图中禁用了垂直滚动 垂直集合视图的单元格计数不是静态的 可以是任意数字 因此 这会产生一个问题 集合视
  • 将 Armadillo C++ 库导入 Xcode

    我是 Mac 用户 正在尝试安装和导入 C Armadillo 库 以下是我到目前为止所采取的步骤 1 我从其网站下载了犰狳库 2 我仔细阅读了下载文件中的 Readme txt 文件 解释了如何安装它 3 我使用CMake将犰狳下载文件制
  • iOS 如何触发视频退出全屏后继续播放?

    我正在构建一个在 iOS 中播放视频的网站 我有一个在 iOS 中工作的全屏按钮 但是退出全屏时视频会暂停 有谁知道一种方法可以强制视频在退出全屏时继续播放 或者如何设置一个侦听器来触发视频在退出全屏时自动播放 这是我的代码
  • 访问 google reader 的 Endpoints API 时出错

    我正在尝试在iPhone APP中实现google reader 到目前为止我已经成功收到了sid and auth 当我尝试使用以下命令调用 Endpoints API 时 问题就出现了GET 这是代码 ASIHTTPRequest re
  • 为arm64或arm7s编译OpenSSL FIPS功能库时出现未知的cpu类型

    我可以成功 至少没有警告并生成 a 文件 针对 arm7 x86 64 和 i386 进行编译 当我编译arm64时 我得到Unknown cpu type 100000c no adjustments made 当我编译arm7s时 我得
  • 使用 BGTaskScheduler 进行后台获取与调试模拟完美配合,但在实践中却不起作用

    我在 appDelegate 的 didFinishLaunchingWithOptions 中注册后台获取任务 BGTaskScheduler shared register forTaskWithIdentifier Backgroun
  • Swift:协议、结构、类

    我开始学习 Swift 语言 但在理解协议 结构和类方面遇到了困难 我来自 Android 方面的编程 所以我相信 Swift 协议基本上是 Java 接口 其中每一个的正确用例是什么 这些类比并不 完全 正确 但这就是我所理解的要点 是的
  • removeItemAtPath 完成

    我正在以这种方式删除路径上的文件 UIPanGestureRecognizer gesture UIPanGestureRecognizer sender UIButton button UIButton gesture view UIPa
  • XCode 7 中的 AWSS3TransferManagerUploadRequest

    我今天升级到 Xcode 7 Swift 2 0 我的项目正在使用 CocoaPods 我正在 POD 文件中导入所有与 AWS 相关的文件 我已经设置了桥接标头 并导入了 Amazon 告诉我的所有文件 在升级到 Swift 2 0 之前
  • iOS Swift 和 reloadRowsAtIndexPaths 编译错误

    我与 xCode Swift 陷入僵局并刷新 UITableView 的单行 这条线有效 self tableView reloadData 而这条线没有 self tableView reloadRowsAtIndexPaths curr
  • 检查 Swift 中关联类型是否符合协议

    在类似情况下 如何检查对象是否符合 可表示 协议 protocol Representable associatedtype RepresentType var representType RepresentType get set cla
  • 无需越狱即可检测iOS9上哪个应用程序处于前台

    我正在尝试记录用户在 iOS9 上的个人应用程序使用情况 我宁愿它不会使用越狱有限的解决方案 不言自明 在越狱手机上执行此应用程序的变体应该不难 https www andyibanez com create mobilesubstrate

随机推荐