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

Posted

技术标签:

【中文标题】UICollectionViewCell 宽度大于我在 sizeForItemAt 中设置的宽度【英文标题】:UICollectionViewCell width is bigger than what I set in sizeForItemAt 【发布时间】:2019-03-28 22:47:47 【问题描述】:

UICollectionView 的宽度/高度与所有可用空间匹配。

我想在一行(两列)中显示两个单元格

所以一个单元格的宽度应该是UICollectionView (collectionView.frame.width / 2) 的一半宽度

所以我以编程方式更改UICollectionViewDelegateFlowLayout函数中单元格的宽度:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    return CGSize(width: collectionView.frame.width / 2.0, height: 150)

但单元格的视觉宽度比collectionView.frame.width / 2.0大得多(在iPhone SE模拟器上测试)

所以它占据了屏幕一半以上的空间

我在这里打印了有关尺寸的信息:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath)
    print("didSelectItemAt \(cell.frame.width), table width: \(collectionView.frame.width), item calc width: \(collectionView.frame.width / 2)")

didSelectItemAt 单元格宽度 187.5,表格宽度:375.0,半角: 187.5

为什么会这样?

边距也有问题,但首先我必须解决这个问题

更新

虽然它适用于 iPhone 6s 模拟器(我编辑了图像以将两个项目放在第一行以检查它们是否合适):

那么 iPhone SE 出了什么问题?

我不想发现其他 iPhone 或 iPad 也可能存在同样的问题

【问题讨论】:

请检查它是否工作正常删除您编写的所有代码并逐步执行***.com/a/54703798/10150796 在我的测试中,当sizeForItemAt 委托方法运行时,它为时过早 并且collectionView.frame.width 仍然错误地报告了设计时大小,该大小取自Interface Builder其当前设置的设备。因此,当在(模拟的)不同设备上运行时,您会看到问题,因为计算错误。你是否也遇到过这种情况? 【参考方案1】:

375.0 是 iPhone 6s 和 X 的尺寸,而不是 iPhone SE 的 320.0

原因是在 iPhone 6s 模式下设置了 collectionView 的宽度约束,但后来切换到 SE 模拟器时,此约束没有更新。

【讨论】:

好的,稍后我会检查约束。对于UICollectionView,我之前将trailing, leading, top, bottom 设置为safe area 我使用自动布局,我相信所有设备的约束都应该以同样的方式工作 也许吧。但是你必须仔细检查不同的设计模式。 发现问题。如果我们将 Collection View Controller 添加到情节提要中,它仅适用于当前选定的 iPhone 设备...太烦人了,我不得不手动添加约束以使 Collection View 适合任何设备的安全区域【参考方案2】:

我认为单元格间距存在问题。您的实现中似乎存在默认单元格间距。您应该尝试以下代码来调整一个原始集合视图中的两个单元格:

extension ViewController : UICollectionViewDelegateFlowLayout

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets 
        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        let collectionViewWidth = collectionView.bounds.width
        return CGSize(width: collectionViewWidth/2, height: 150)
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat 
        return 0
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat 
        return 0
    

此外,您应该检查UICollectionView 的约束是否符合您的要求。

【讨论】:

【参考方案3】:

尝试使用视图中的 Wide,而不是 collectionView。

试试这个:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    return CGSize(width: (view.frame.width / 2.0) - 5, height: 150) // provide little bit space between cells

希望这会有所帮助。

【讨论】:

【参考方案4】:

最好的解决方案是,在主线程中重新加载您的集合视图,并稍作延迟。

   DispatchQueue.main.asyncAfter(deadline: .now() + 0.10) 
       self.myCollectionView.reloadData()
   

【讨论】:

以上是关于UICollectionViewCell 宽度大于我在 sizeForItemAt 中设置的宽度的主要内容,如果未能解决你的问题,请参考以下文章

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

UICollectionViewCell -- 使 selectedBackgroundView 比单元格本身大

UICollectionViewCell 不填充屏幕宽度

UICollectionViewCell 在 UICollectionViewReusableView 宽度之后开始

以编程方式将 UICollectionViewCell 宽度设置为 UICollectionView 宽度

单击按钮 UICollectionViewCell 宽度和高度更改