如何以编程方式使 UICollectionView 填充 UITableViewCell?

Posted

技术标签:

【中文标题】如何以编程方式使 UICollectionView 填充 UITableViewCell?【英文标题】:How can I programmatically make a UICollectionView fill a UITableViewCell? 【发布时间】:2018-01-22 22:16:52 【问题描述】:

我正在尝试做一些相当简单的事情,但我不断收到错误。

我有一个包含多个部分的 UITableView。每个部分都有一个标题和一个 UITableViewCell。每个单元格中都有一个 UICollectionView。所有这些视图都必须以编程方式创建(我不能使用情节提要解决方案)。

问题是当我尝试调整 UICollectionView 的大小和位置时。我希望 UICollectionView 填充整个 UITableViewCell,所以起初我尝试使用 self.frame 在 UITableViewCell 的 init 方法中调整 UICollectionView 的大小,如下所示:

var collectionView: UICollectionView? 让collectionViewLayout:UICollectionViewFlowLayout! 覆盖初始化(样式:UITableViewCellStyle,reuseIdentifier:字符串?) self.collectionViewLayout = UICollectionViewFlowLayout() self.collectionViewLayout.sectionInset = UIEdgeInsets(上:1.0,左:1.0,下:1.0,右:1.0) self.collectionViewLayout.scrollDirection = .vertical super.init(风格:风格,reuseIdentifier:reuseIdentifier) 让 frame = CGRect(x: 0.0, y: 0.0, width: self.frame.width, height: self.frame.height) self.collectionView = UICollectionView(frame: frame, collectionViewLayout: self.collectionViewLayout) self.collectionView?.dataSource = self self.collectionView?.delegate = self

但是,我认为此时没有设置 UITableViewCell 的框架(init 方法调用),因此 UICollectionView 的大小不正确。那是对的吗?

接下来,我尝试使用布局锚点,如下所示:

collectionView?.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true

这给了我一个布局约束错误,并说“UICollectionViewProject[63851:2306772] [LayoutConstraints] 无法同时满足约束。”我不明白这怎么可能。我只添加了一个约束,情节提要中什么都没有,它可能会破坏哪些约束?

不知何故,我需要使这个 UICollectionView 与 UITableViewCell 大小相同,并完美地放入其中。

【问题讨论】:

【参考方案1】:

在您的代码中,您只添加了 1 个constraint - bottomAnchorAutolayout 不能那样工作。只需在将UICollectionView 添加为subviewUITableViewCell 之后添加所有必需的constraints,即

override init(style: UITableViewCellStyle, reuseIdentifier: String?)

    super.init(style: style, reuseIdentifier: reuseIdentifier)

    self.collectionViewLayout = UICollectionViewFlowLayout()
    self.collectionViewLayout.sectionInset = UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)
    self.collectionViewLayout.scrollDirection = .vertical

    let frame = CGRect(x: 0.0, y: 0.0, width: self.frame.width, height: self.frame.height)
    self.collectionView = UICollectionView(frame: frame, collectionViewLayout: self.collectionViewLayout)
    self.collectionView?.translatesAutoresizingMaskIntoConstraints = false
    self.addSubview(self.collectionView!)

    NSLayoutConstraint.activate([
        self.collectionView!.topAnchor.constraint(equalTo: self.topAnchor),
        self.collectionView!.bottomAnchor.constraint(equalTo: self.bottomAnchor),
        self.collectionView!.leftAnchor.constraint(equalTo: self.leftAnchor),
        self.collectionView!.rightAnchor.constraint(equalTo: self.rightAnchor),
        ])

    self.collectionView?.dataSource = self
    self.collectionView?.delegate = self

【讨论】:

感谢 PGDev!我的原始代码中缺少的一段关键代码是 translatesAutoresizingMaskIntoConstraints = false。如果没有将该属性设置为 false,则约束将不起作用。 当然..快乐编码..:)【参考方案2】:

您为集合视图设置的大小将根据自动布局(从集合视图默认自动调整大小掩码自动转换)被覆盖,因此您需要设置适当的约束。

如果您希望您的集合视图填满整个单元格,请尝试在 init 方法的末尾添加以下代码:

collectionView.translatesAutoresizingMaskIntoConstraints = false
addSubview(collectionView)

let layoutAttributes: [NSLayoutAttribute] = [.top, .bottom, .leading, .trailing]
let constraints = layoutAttributes.map 
    NSLayoutConstraint(item: self, attribute: $0, relatedBy: .equal, toItem: collectionView, attribute: $0, multiplier: 1.0, constant: 0.0)

NSLayoutConstraint.activate(constraints)

然后,您必须计算集合视图的高度,并在方法tableView(_:, heightForRowAt:) 中告诉您的表视图委托。

【讨论】:

Ferschae,缺少的部分是 collectionView?.translatesAutoresizingMaskIntoConstraints = false。当我添加那段代码时,您的建议非常有效。请更新您的答案以包含那段代码。谢谢。 当然!默认的自动调整大小蒙版约束与这些约束冲突!

以上是关于如何以编程方式使 UICollectionView 填充 UITableViewCell?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式创建和使用 UIcollectionView?

如何以编程方式快速创建 uicollectionview(没有情节提要)

如何以编程方式推送 UICollectionView? [复制]

如何以编程方式在 UICollectionView 上添加自动布局?

如何根据 UICollectionView 的部分以编程方式更新标签

如何以编程方式创建 UICollectionView