从未调用过CollectionView sizeForItemAtIndexPath


92

这真让我抓狂!我有一个UICollectionViewController,如下所示:

class PhrasesCompactCollectionViewController: UICollectionViewController

正在调用numberOfSections和cellForItemAt,但从不调用sizeForItemAtIndexPath。我在其他地方使用了完全相同的代码,并且可以正确触发。我正在使用Xcode 8 Beta 6。

func collectionView(collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAtIndexPath indexPath:  NSIndexPath) -> CGSize {

        return CGSize(width: 120, height:120) 
    }

Answers:


250

您需要指定UICollectionViewDelegateFlowLayout在类声明中实现协议。

class PhrasesCompactCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout


10
我这样做了,但仍未调用。:(
Van Du Tran

57

Swift 3+中,请使用以下方法:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width:(collectionView.frame.height-90)/2, height: 100)
}

确保您的班级符合两个委托

  • UICollectionViewDelegate

  • UICollectionViewDelegateFlowLayout


4
遵循UICollectionViewDelegateUICollectionViewController已经这样做是多余的。
Van Du Tran

2
@VanDuTran声明它是必需的,因为不需要UICollectionViewController是不必要的……
Michael Hudson

我认为您的意思是,非集合视图Viewcontroller可以是UICollectionViewDelegate。
ScottyBlades

1
UICollectionViewDelegateFlowLayout继承自UICollectionViewDelegate,因此只需实现UICollectionViewDelegateFlowLayout
evya

43

我有同样的问题。帮助我的一件事是在collectionView大小检查器“无”下为单元格大小设置了“估计大小”。

在此处输入图片说明


8
您保存了我的好友,您是英雄
Asif Ali,

1
不知何故,关于使用的所有其他帖子上的所有其他答案都sizeForItemAt没有提到这一点。很有用。
JCutting8

这太疯狂了!!!!我在iPhone 5模拟器上测试了iOS版本10.3.1,并调用了该方法。在iPhone 5s模拟器上使用10.3.1版本的方法无法调用!!!我将“估计大小”更改为“无”。它开始在iPhone 5s上被调用。WT WT WT
哈桑

非常感谢!sizeForItemAt直到Xcode 11.4突然单元格宽度错误时,我的自定义集合视图效果良好。尝试了一堆东西,这终于奏效了。
Filip

你节省了我的时间。非常感谢。
Shahbaz Akram

15

迅捷3

要设置UICollectionView的单元格大小,您需要创建和自定义对象UICollectionViewFlowLayout。自定义属性并将该布局对象设置为UICollectionView对象。

根据您的要求(所需的像元高度和宽度)更改cellheight和cell cellWidth对象。

override func viewDidLoad() {
    super.viewDidLoad()

    let cellWidth : CGFloat = myCollectionView.frame.size.width / 4.0
    let cellheight : CGFloat = myCollectionView.frame.size.height - 2.0
    let cellSize = CGSize(width: cellWidth , height:cellheight)

    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .vertical //.horizontal
    layout.itemSize = cellSize
    layout.sectionInset = UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1)
    layout.minimumLineSpacing = 1.0
    layout.minimumInteritemSpacing = 1.0
    myCollectionView.setCollectionViewLayout(layout, animated: true)

    myCollectionView.reloadData()
}

确保:如果添加了sizeForItemAt indexPath方法,则必须删除该方法...

删除以下方法

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

}

12
这有什么帮助?
almas

1
阿尔玛斯,这将有助于设置UICollectionViewCell的自定义单元格大小...有变量cellWidth和cellHeight,您可以定义自己的值...以及“ layout.sectionInset”,“ layout.minimumLineSpacing”和“ layout” .minimumInteritemSpacing”,这些变量也很重要的UICollectionViewCell大小..
拉夫拉米

2
仅当所有像元大小相同时,此方法才有效。以下答案是正确的答案
JeffN

这是用于更改UICollectionView的大小,而不是视图内部的单元格
Async- '17

这不是为什么不调用委托方法的答案
Ziv Kesten

10

迅捷5

所有这些步骤都是必需的

  1. 符合UICollectionViewDelegateFlowLayout <==绝对需要!!
  2. UICollectionViewDelegate, UICollectionViewDataSource
  3. 在viewDidLoad中设置它们: collectionView.delegate = selfcollectionView.dataSource = self
  4. 估算大小设置为无在“界面生成器”中将“ ”
  5. 确保以下方法具有sizeForItemAt而不是sizeForItemAtIndexPath

如下:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
    return CGSize(width: 100, height:100)
} 

1
估计大小为无-保存我的一天!
乔·哈伦贝克

6

第一类需要确认到UICollectionViewDelegateFlowLayout。然后,您需要在viewDidLoad()中编写以下代码:

//告诉UICollectionView使用UIViewController的UICollectionViewDelegateFlowLayout方法

collectionView.delegate = self

//如果要设置自己的收藏视图流布局

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical //depending upon direction of collection view

self.collectionView?.setCollectionViewLayout(layout, animated: true)

通过使用此代码,UICollectionViewDelegateFlowLayout方法

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize

将被调用,您可以在此方法中设置大小。


4

您需要检查以下三件事:

  1. 实施FlowLayout委托: class MyController: UICollectionViewController, UICollectionViewDelegateFlowLayout

  2. 快速3.0+的商品尺寸使用方法: func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: (collectionView.frame.width / 3) - 1, height: collectionView.frame.width) }

  3. 选择Estimate size = None在检查UICollectionView的元素。


2

我有同样的问题,没有任何办法可以解决。我有一个黄色警告说要使其私有,因为它接近布局代表定义的另一个功能。对我来说固定的是:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize

注意从“ sizeForItemAtIndexPath”到正确的“ sizeForItemAt”的区别。

为了解决这个问题,我将头发扯了好几天,终于成功了。下面,我将包括所有功能,向您展示如何通过使高度等于0来“隐藏”一个单元格。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let findIndex = labelArray.index(of: "\(labelArray[indexPath.row])")
    let screenSize = UIScreen.main.bounds
    let screenWidth = screenSize.width

    if (findIndex! % 2 == 0){
        // Even index, show cell
        return CGSize(width: screenWidth, height: 246)
    }
    else {
        return CGSize(width: screenWidth, height: 0)
    }
}

0

我昨晚有这个问题。终于在午夜解决了这个问题,当时我意识到'didSelectItemAtIndex'方法没有用右括号“}”关闭

当编译错误询问时,我在类的最底部添加了一个闭合括号。因此,实际上,“ didSelectItemAtIndex”下面的所有方法都在该方法内部。

张贴在这里,以防万一其他人在这个晚上浪费了四个小时:-(


0

确保将其放入viewDidLoad()

collectionView.delegate = self

0

我的问题是我将UICollectionViewDataSource对象创建为局部变量。因此,如果您在代码中手动初始化dataSource对象,请确保将其存储为全局变量。


0

使用这个方法

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

}

代替

private func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

}

-11

对于我(在Swift 3.1中),该方法必须像这样声明为public:

    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
       return CGSize()
    }

别忘了公开它。


public是用来使代码在框架和模块之间可访问的。
ScottyBlades
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.