从未调用CollectionView sizeForItemAtIndexPath

时间:2016-08-23 17:33:37

标签: ios

这让我抓狂!我有一个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) 
    }

18 个答案:

答案 0 :(得分:201)

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

class PhrasesCompactCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout

答案 1 :(得分:38)

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

答案 2 :(得分:17)

快捷键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)
} 

答案 3 :(得分:12)

Swift 3

要设置UICollectionView的Cell Size,您需要创建和自定义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 {

}

答案 4 :(得分:12)

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

enter image description here

答案 5 :(得分:4)

第一类需要确认到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

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

答案 6 :(得分:1)

只需添加:UICollectionViewDelegateFlowLayout

class YourClass: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {}

答案 7 :(得分:0)

我通过调用解决了同样的问题

collectionView.delegate = self

之前

collectionView.dataSource = self

我有静态项目,从不重新加载数据。 显然,设置 dataSource 会触发同步加载集合数据,因此如果此时未设置委托,则永远不会调用 sizeForItemAtIndexPath(除非稍后调用 reloadData)。

答案 8 :(得分:0)

你是否设置了错误的布局:UICollectionViewLayout,实际上这个布局应该是UICollectionViewFlowLayout这样的

答案 9 :(得分:0)

使用此方法

Public Sub resetDVs()
    [A1:A10] = Range("G1").Value
End Sub

代替

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

}

答案 10 :(得分:0)

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

答案 11 :(得分:0)

如果没有答案,您需要做的三件事:

  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. 在UICollectionView的Inspect元素中选择Estimate size = None

答案 12 :(得分:0)

我遇到了同样的问题,没有办法解决。我有一个黄色警告说要使其私有,因为它接近由布局委托定义的另一个功能。对我来说固定的是:

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)
    }
}

答案 13 :(得分:0)

确保将其放入viewDidLoad()

collectionView.delegate = self

答案 14 :(得分:0)

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

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

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

答案 15 :(得分:-1)

如果您使用的是 autolayout,请确保设置了 collectionView.translatesAutoresizingMaskIntoConstraints = false

答案 16 :(得分:-1)

不要忘记使用 UICollectionViewDelegateFlowLayout。在 xib/storyboard 中设置间距并使用以下更新的函数调整单元格的大小,以适用于较新的 Swift 版本。快乐编码!!

   @objc(collectionView:layout:sizeForItemAtIndexPath:)
func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize {
    let numberOfItemsPerRow:CGFloat = 5
    
    if let collection = self.collectionView {
        let width = collection.bounds.width / numberOfItemsPerRow
        
        return CGSize(width: width, height: 36)
    }else{
        return CGSize(width: 0, height: 0)
    }
}

答案 17 :(得分:-9)

对于我(在Swift 3.1中),必须将此方法声明为public:

IndexError: arrays used as indices must be of integer (or boolean) type

不要忘记将其设为公开