UITableViewCell 中加载 UIView 的 Nib 文件不会拉伸

2023-12-15

我有一个 UIView,可以通过 nib/xib 文件重用。我想加载它并填充一个 UITableViewCell,它将在自动调整大小的 UITableView 中使用。全部带有自动布局。

大多数工作都很好,但似乎加载的 UIView 使用周围添加的约束来缩小 UITableViewCell 的 contentView。这对高度有利,但我不希望对宽度如此。

How the UITableViewCell looks Ignore the grey cell below, this is just a selected cell.

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let cellId = "RowView0002"
    var cell = tableView.dequeueReusableCell(withIdentifier: cellId)
    if cell == nil {
        cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: cellId)

        let subView = RowView(frame: cell!.frame)

        cell!.contentView.attachViewWithConstraints(subView)
        let _ = subView.viewLoadedFromNibAttached(name: cellId)

    }

    return cell!
}

override public func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self
    tableView.estimatedRowHeight = 40.0
    tableView.rowHeight = UITableViewAutomaticDimension
}

extension UIView
{
    public func attachViewWithConstraints(_ view:UIView)
    {
        addSubview(view)
        view.translatesAutoresizingMaskIntoConstraints = false
        view.layoutAttachAll(to: self)
    }

    @discardableResult
    public func viewLoadedFromNibAttached<T : UIView>(name:String) -> T? {
        guard let view = Bundle.main.loadNibNamed(name, owner: self, options: nil)?[0] as? T else {
            return nil
        }
        attachViewWithConstraints(view)
        return view
    }

    public func layoutAttachAll(to childView:UIView)
    {
        var constraints = [NSLayoutConstraint]()

        childView.translatesAutoresizingMaskIntoConstraints = false
        constraints.append(NSLayoutConstraint(item: childView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0))
        constraints.append(NSLayoutConstraint(item: childView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0))
        constraints.append(NSLayoutConstraint(item: childView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0))
        constraints.append(NSLayoutConstraint(item: childView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0))

        childView.addConstraints(constraints)
    }

在 RowView0002.xib 中,我将 rootviews 背景设置为红色,添加了一个带有 4 个约束的 UILabel,其侧面有一些边距,如您所见。我都尝试将 rootView 设置为 RowView 类及其文件所有者。两者都“有效”。

知道如何让 contentView 与 UITableView 匹配吗?

*编辑1: 绿色是 UILabel 的背景。红色是 nib 文件的背景。运行应用程序后,视图继承关系为:UITableViewCell > ContentView > RowView > NibFileView(红色)> UILabel(绿色)

检查视图层次结构表明所有约束均按预期设置。然而 UITableViewContentView 有与所看到的总大小匹配的约束(错误):

self.width = 156.5 @ 1000

下面是layoutAttachAll 的完整实现。

首先是一些用法示例:

 // pin all edge to superview
 myView.layoutAttachAll()

 // pin all edges (to superview) with margin:
 myView.layoutAttachAll(margin: 8.0)

 // for child views: pin leading edge to superview's leading edge:
 myView.layoutAttachLeading()

 // for sibling views: pin leading edge to siblingView's trailing edge:
 myView.layoutAttachLeading(to: siblingView)

 // for sibling views: pin top edge to siblingView's bottom edge:
 myView.layoutAttachTop(to: siblingView)

注意:myView必须添加为子视图在附加到超级视图之前使用这些方法。此外,所有参与视图都必须设置translatesAutoresizingMaskIntoConstraints = false。

完整实施:

import UIKit

extension UIView {

    /// attaches all sides of the receiver to its parent view
    func layoutAttachAll(margin : CGFloat = 0.0) {
        let view = superview
        layoutAttachTop(to: view, margin: margin)
        layoutAttachBottom(to: view, margin: margin)
        layoutAttachLeading(to: view, margin: margin)
        layoutAttachTrailing(to: view, margin: margin)
    }

    /// attaches the top of the current view to the given view's top if it's a superview of the current view, or to it's bottom if it's not (assuming this is then a sibling view).
    /// if view is not provided, the current view's super view is used
    @discardableResult
    func layoutAttachTop(to: UIView? = nil, margin : CGFloat = 0.0) -> NSLayoutConstraint {

        let view: UIView? = to ?? superview
        let isSuperview = view == superview
        let constraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: view, attribute: isSuperview ? .top : .bottom, multiplier: 1.0, constant: margin)
        superview?.addConstraint(constraint)

        return constraint
    }

    /// attaches the bottom of the current view to the given view
    @discardableResult
    func layoutAttachBottom(to: UIView? = nil, margin : CGFloat = 0.0, priority: UILayoutPriority? = nil) -> NSLayoutConstraint {

        let view: UIView? = to ?? superview
        let isSuperview = (view == superview) || false
        let constraint = NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: isSuperview ? .bottom : .top, multiplier: 1.0, constant: -margin)
        if let priority = priority {
            constraint.priority = priority
        }
        superview?.addConstraint(constraint)

        return constraint
    }

    /// attaches the leading edge of the current view to the given view
    @discardableResult
    func layoutAttachLeading(to: UIView? = nil, margin : CGFloat = 0.0) -> NSLayoutConstraint {

        let view: UIView? = to ?? superview
        let isSuperview = (view == superview) || false
        let constraint = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: view, attribute: isSuperview ? .leading : .trailing, multiplier: 1.0, constant: margin)
        superview?.addConstraint(constraint)

        return constraint
    }

    /// attaches the trailing edge of the current view to the given view
    @discardableResult
    func layoutAttachTrailing(to: UIView? = nil, margin : CGFloat = 0.0, priority: UILayoutPriority? = nil) -> NSLayoutConstraint {

        let view: UIView? = to ?? superview
        let isSuperview = (view == superview) || false
        let constraint = NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: isSuperview ? .trailing : .leading, multiplier: 1.0, constant: -margin)
        if let priority = priority {
            constraint.priority = priority
        }
        superview?.addConstraint(constraint)

        return constraint
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UITableViewCell 中加载 UIView 的 Nib 文件不会拉伸 的相关文章

随机推荐

  • typedef 模板声明的替代方案

    我正在努力实现 namespace NTL typedef std valarray vector 通过标准 C 我知道这是不允许的 但我需要一种快速且简单的方法 无需重新实现所有函数 运算符 重载等 来获取模板 typedef 我现在正在
  • 如何使用 C# 从 URL 下载 ZIP 文件?

    我想从某个网址下载 ZIP 文件 当我打开浏览器并输入 URL 时 浏览器会直接开始下载 ZIP 文件 但是我想要的是使用 C 代码自动执行此操作 我尝试过以下代码 private void btnDownload Click object
  • python 绘制多重图

    我尝试使用 graphviz 在 Python 中绘制多重图 现在我可以用 Python 绘制常用的图表 如下所示 import pygraphviz as pgv G pgv AGraph G add node a G add node
  • 空手道-如何仅在失败的情况下自动重新运行[重复]

    这个问题在这里已经有答案了 空手道中是否有任何方法可以在同一执行中自动仅重新运行 UI 测试自动化失败的场景 甚至在 API 中 我使用 gradle 作为构建工具 这是我这边的要求 如果任何测试失败 应该再次重试 如果我们可以在每个功能场
  • Firestore - 使用数组添加对象

    一整天都在这里用这个东西自杀 我正在上两门课 系和文章 export class Department articals Artical moms number id string constructor and export class
  • 如何使用 jQuery 获取、操作和替换文本节点?

    这是我的代码 li class det price a href designer customize 278258 dpid 1 Printing a from 10 li 我在任何给定页面上都有大约十五个这样的块 我想获取文本节点 来自
  • 从 ANT 启动 Eclipse 运行配置

    我正在将 Orion 服务器用于基于 Java 的 Web 应用程序 我有一个运行配置 可以使用正确的类路径和所有必要的配置启动 Orion 我还有几个 ANT 脚本用于将文件复制到构建路径 我想创建一个 ANT 脚本来关闭 Orion 复
  • 如何用Python从LDA模型生成词云?

    我正在对报纸文章进行一些主题建模 并使用 Python3 中的 gensim 实现了 LDA 现在我想为每个主题创建一个词云 使用每个主题的前 20 个单词 我知道我可以打印单词 并保存 LDA 模型 但是有没有办法只保存每个主题的顶部单词
  • 用C解析和读取数据帧?

    我正在编写一个从Linux上的串口读取数据的程序 数据由另一台设备发送 帧格式如下 start Command Data CRC End 0x02 0x41 0 127 octets 0x03 数据字段包含 127 个八位位组 如图所示 八
  • 为每个单选按钮分配 2 个值

    我试图为每个单选按钮分配 2 个值 以在 2 个字段中输出 但这不起作用 这是我使用的代码 p What s your favorite browser p
  • 我是否误解了heredoc应该做什么?

    我对 PHP 很陌生 所以我知道我在这里遗漏了一些明显的东西 我认为heredoc函数应该保留格式 换行符等 但每当我测试它时 它解析时都没有格式化 我尝试了很多不同的脚本 包括来自 PHP net 和 W3schools 等来源的复制粘贴
  • Excel VBA 在函数中合并单元格

    我编写了一个粗略的函数来根据范围选择和连接单元格 Function GetSkills CellRef As String CellRefEnd As String Delimiter As String Dim CellStart As
  • 非整数的错误“整数输入语法无效”?

    我正在使用 Python 和 psycopg2 我正在尝试执行带有值列表的准备好的语句 如下所示 cur callproc prepared func prepared values psycopg2 DataError invalid i
  • 无法在 xcode 4.2 上构建我的项目

    我已将我的 xcode 升级到 4 2 使用雪豹 以前我使用的是 Xcode 3 2 6 我的项目使用它成功构建 现在我无法构建它 而是 Xcode 发出以下错误 ld warning option A is obsolete and be
  • 将生成的 img 嵌入 django 模板中

    我如何将生成的图像嵌入 django 模板中 就像是 return render to response graph html img get graph 我不想要这个 因为它只是发送图像 http HttpResponse get gra
  • FFmpeg从mp4创建m3u8,视频文件大小

    我正在使用 ffmpeg 将 mp4 转换为 m3u8 但首先我需要让 mp4 变小 我使用这段代码来缩小它 ffmpeg i big mp4 b 1000000 small mp4 然后我使用这段代码将其转换为m3u8 ffmpeg i
  • Vue 3 自定义复选框组件,带有 v-model 和项目数组

    迫切需要你们的帮助 所以基本上我有一个带有 v 模型的自定义复选框组件 我在组件上使用 v for 循环来显示带有数组中名称的复选框 在父组件中 我有两列 可用 和 选定 这个想法是 如果我选中其中一个框可用栏它应该出现在选定的列 问题是它
  • 设置 win32 控制台应用程序的库路径

    当我尝试执行简单的 HelloWorld win32 控制台应用程序时 出现 找不到 dll 重新启动应用程序可能会解决问题 错误 我知道 dll 的位置 从命令提示符执行 exe 时如何指定其位置 PS 将 dll复制到 exe的当前目录
  • Doctrine2:这些实体之间的关联有什么问题?

    我正在尝试通过简单的示例来了解 Doctrine2 中的所有更改 请查看以下实体片段 VCat php namespace Application Models Entity Table name v cat class VCat Id C
  • UITableViewCell 中加载 UIView 的 Nib 文件不会拉伸

    我有一个 UIView 可以通过 nib xib 文件重用 我想加载它并填充一个 UITableViewCell 它将在自动调整大小的 UITableView 中使用 全部带有自动布局 大多数工作都很好 但似乎加载的 UIView 使用周围