如何在 collectionView 单元格中设置 NSLayoutConstraint 常量?

Posted

技术标签:

【中文标题】如何在 collectionView 单元格中设置 NSLayoutConstraint 常量?【英文标题】:How to set NSLayoutConstraint constant in a collectionView cell? 【发布时间】:2018-11-27 20:01:22 【问题描述】:

在我的故事板中,我对单元格中的子视图(称为缩略图)有一组约束

然后在我的自定义 collectionView 单元格中:

类 PostViewCell: UICollectionViewCell

var portrait: Bool? 
    didSet 
        if portrait == true 
            print(self.bounds.height)
            thumbnailWidthConstraint.constant = self.bounds.width
            thumbnailHeightConstraint.constant = self.bounds.height/2
            thumbnailHeightConstraint.isActive = true
         else 
            thumbnailWidthConstraint.constant = self.bounds.width/2
            thumbnailHeightConstraint.constant = self.bounds.height
        
        self.layoutIfNeeded()
    

@IBOutlet weak var thumbnailCenterYConstraint: NSLayoutConstraint!
@IBOutlet weak var thumbnailWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var thumbnailHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var thumbnailCenterXConstraint: NSLayoutConstraint!

override func layoutSubviews() 
    if self.bounds.width > self.bounds.height 
        portrait = false
     else 
        portrait = true
    
    super.layoutSubviews()

我的目标是改变缩略图的高度和宽度,就像你在肖像变量的 didSet 方法中看到的那样。然而,到目前为止,这似乎并不成功。它打印 536 的 self.bounds.height ,在应用程序中它似乎是这个高度,而不是我试图在约束中设置的高度的一半。我错过了什么步骤?为什么这不起作用?谢谢!

编辑:在包含我拥有的 collectionView 单元格的视图控制器中:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) 
    postsCollectionView.collectionViewLayout.invalidateLayout()
    postsCollectionView.layoutIfNeeded()
    super.viewWillTransition(to: size, with: coordinator)

这个集合视图在我的视图控制器中被称为“postsCollectionView”。另外,我有这个:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    if collectionView == timelineCollectionView 
        return CGSize(width: CGFloat(2.5), height: collectionView.bounds.height)
     else 
        return CGSize(width: collectionView.bounds.size.width, height: collectionView.bounds.size.height)
    

因此,当我旋转手机时,collectionView 变得比高度更宽,里面的单元格也是如此。这有望将单元格设置为重新布局子视图并更改我定义的约束。

【问题讨论】:

您将 self(一个 UIColelctionViewCell)作为您的尺寸参考。定义单元格大小的代码在哪里。此单元格的大小是否会根据方向而变化? @Dare 我为 collectionView 添加了我的视图控制器的 sizeForItemAt,它使每个单元格的高度和宽度等于 collectionView 的高度和宽度。当设备旋转到横向模式时,collectionView 变得比高度更宽,并且我的自定义单元格类中的 Portrait 变量被更改为 false。 【参考方案1】:

更改常量后可能会错过重新布局

var portrait: Bool? 
    didSet 
        if portrait == true 
            print(self.bounds.height)
            thumbnailWidthConstraint.constant = self.bounds.width
            thumbnailHeightConstraint.constant = self.bounds.height/2
            thumbnailHeightConstraint.isActive = true
         else 
            thumbnailWidthConstraint.constant = self.bounds.width/2
            thumbnailHeightConstraint.constant = self.bounds.height
        

        self.layoutIfNeeded() // or  self.contentView.layoutIfNeeded() 
    


您还需要响应系统方向的变化

func viewWillTransition(to size: CGSize, 
               with coordinator: UIViewControllerTransitionCoordinator) 
  collectionView.collectionViewLayout.invalidateLayout()
  collectionView.layoutIfNeeded()

【讨论】:

谢谢。我已将这些更改包含在问题中,以便您可以查看我的实现。不幸的是,缩略图仍然显示为全高。 你能评论这个thumbnailHeightConstraint.isActive = true,好像它的横向控制不会去激活,并在你设置约束的地方激活它吗? 你的意思是把它注释掉?是的,我用//注释掉了它,缩略图仍然显示为全高。我不确定你的意思 - 你只是说不需要? 你根据 if self.bounds.width > self.bounds.height 你是否使用 sizeForItem 配置了单元格所以它的横向/纵向大小变化?? 啊,是的,我在 sizeForItem 中配置了它,使其与 collectionView 本身的宽度和高度相同。如果在横向模式下,collectionView 本身会变得比高度更宽,而在纵向模式下则相反。我已编辑问题以包含此

以上是关于如何在 collectionView 单元格中设置 NSLayoutConstraint 常量?的主要内容,如果未能解决你的问题,请参考以下文章

如何仅为一个 indexPath.row 项目在 CollectionView 单元格中设置动画?

Swift - 在CollectionView中设置不同宽度的单元格之间的固定间距

如何在 CollectionView iOS Swift 4 中显示不显示单元格的标题?

UICollectionViewCell宽度大于我在sizeForItemAt中设置的宽度

如何在 DataSet 中设置单元格?帮助!

如何在 UITableView 中设置单元格高度?