如何将 UIView 约束为 UICollectionViewCell

Posted

技术标签:

【中文标题】如何将 UIView 约束为 UICollectionViewCell【英文标题】:How do I constrain UIView to UICollectionViewCell 【发布时间】:2016-11-21 15:12:46 【问题描述】:

与其他人似乎在问什么相反。我有一个带有单元格的collectionView,我在其中添加了一个加载的.xib 作为子视图。很容易。

但是,collectionView 单元格的大小在运行时会根据不同的标准发生变化,因此我需要将子视图适当地限制为 collectionViewCell 的 contentView 的大小。为了尝试做到这一点,我在添加子视图时有以下代码:

/**
Used to present a view in the collectionView. WidetView is a subclass of UIView
*/
class WidgetCell: UICollectionViewCell, Reusable 
    var widgetView: WidgetView! 
        didSet 
            for view in contentView.subviews 
                view.removeFromSuperview()
            

            contentView.addSubview(widgetView)
            let views = ["view": widgetView as Any]
            var constraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: views)
            constraints.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: views))

            contentView.addConstraints(constraints)
        
    

不幸的是,所呈现的并不是一组受到适当约束的视图。添加的 UIView 与 .xib 中定义的大小相同。

我该如何解决这个问题?如果你想要一个示例项目(Swift 3),请看这里:https://github.com/AaronBratcher/FitToCell

【问题讨论】:

发现了我的问题。我想设置添加的 UIView 的框架以匹配 contentView.frame,而不是使用约束。 很高兴您找到了解决方案,但请注意,这样做意味着如果您转动设备横向,框架将不会更新,您必须手动完成。 原来 contentView 的大小并不总是合适的。我需要将单元格大小传递给 WidgetCell 类并将 widgetView.frame.size 设置为那个 【参考方案1】:

这是一个简单的例子,使用现有代码调用contentView.activateConstraints(constraints),然后在显示单元格的位置cell.layoutIfNeeded()。这会强制单元格重新计算其子视图的边界。

【讨论】:

一个好主意,我研究了一下。新添加的约束默认处于活动状态,并使用 NSLayoutConstraint 类激活/停用。无论如何,我确实尝试了在创建 collectionViewCell 时激活约束并设置 layoutIfNeeded 的建议,但没有帮助。如果您还有其他想法,请尝试有关该项目的想法。【参考方案2】:

由于单元格的预期大小对于布局目的是已知的,因此将该大小传递给 WidgetCell 实例,然后设置视图的框架大小。

final class WidgetCell: UICollectionViewCell 
    var cellSize: CGSize?
    var widgetView: WidgetView! 
        didSet 
            for view in contentView.subviews 
                view.removeFromSuperview()
            

            let frame: CGRect
            if let cellSize = cellSize 
                frame = CGRect(origin: CGPoint(x: 0, y: 0), size: cellSize)
             else 
                frame = contentView.frame
            

            widgetView.frame = frame
            widgetView.setNeedsLayout()
            contentView.addSubview(widgetView)
        
    

【讨论】:

以上是关于如何将 UIView 约束为 UICollectionViewCell的主要内容,如果未能解决你的问题,请参考以下文章

使用编程约束时如何将 CAGradientLayer 添加到 UIView

如何获取 snapkit 为 UIView 声明的高度约束?

如何将自动布局约束与 UIView 的 contentMode 属性结合起来

swift - 在UIScrollView上从xib添加UIView后如何更新约束?

如何动态设置 UIView 约束?

以百分比指定两个 UIView 的约束