CollectionView sizeForItemAtIndexPath nunca chamado


92

Isto está me enlouquecendo! Eu tenho um UICollectionViewController conforme mostrado abaixo:

class PhrasesCompactCollectionViewController: UICollectionViewController

NumberOfSections e cellForItemAt estão sendo chamados, mas sizeForItemAtIndexPath nunca é chamado. Estou usando exatamente o mesmo código em outro lugar e ele dispara corretamente. Estou usando o Xcode 8 Beta 6.

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

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

Respostas:


250

Você precisa especificar que implementa o protocolo UICollectionViewDelegateFlowLayoutem sua declaração de classe.

class PhrasesCompactCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout


10
Eu fiz isso, mas ainda não foi chamado. :(
Van Du Tran

57

Em Swift 3+, use este método:

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

Certifique-se de que sua classe está em conformidade com ambos Delegado

  • UICollectionViewDelegate

  • UICollectionViewDelegateFlowLayout


4
É redundante obedecer ao UICollectionViewDelegateUICollectionViewController.
Van Du Tran

2
@VanDuTran Não é redundante afirmar que é necessário porque ser um UICollectionViewController não é necessário ...
Michael Hudson

Eu acho que você quis dizer que uma visão sem coleção, Viewcontroller pode ser o UICollectionViewDelegate.
ScottyBlades de

1
UICollectionViewDelegateFlowLayout herda de UICollectionViewDelegate, então apenas implemente o UICollectionViewDelegateFlowLayout
evya

43

Eu tive o mesmo problema. A única coisa que me ajudou foi fazer o 'Tamanho estimado' para o tamanho da célula no inspetor de tamanho de collectionView 'Nenhum'.

insira a descrição da imagem aqui


8
Você salvou meu dia, amigo, você é um herói
Asif Ali

1
De alguma forma, todas as outras respostas em todas as outras postagens sobre o uso sizeForItemAtnão mencionaram isso. Muito útil.
JCutting8

Isso é loucura!!!! Testei no simulador do iPhone 5 com a versão 10.3.1 iOS e o método foi chamado. no simulador do iPhone 5s com o método da versão 10.3.1 não é chamado !!! Mudei o tamanho estimado para nenhum. Ele começou a ser chamado no iPhone 5s. WT WT WT
hasan

Muito obrigado! Minha visualização de coleção com customização sizeForItemAtfuncionou bem até o Xcode 11.4 quando de repente as células estavam com a largura errada. Tentei um monte de coisas e isso finalmente funcionou.
Filip

Você salvou meu tempo. Muito obrigado.
Shahbaz Akram

15

Swift 3

Para definir o tamanho da célula de UICollectionView, você precisa criar e personalizar o objeto de UICollectionViewFlowLayout. Personalize as propriedades e defina esse objeto de layout para o objeto UICollectionView.

Altere os objetos cellheight e cellWidth da célula de acordo com seus requisitos (a altura e largura da célula que você deseja).

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

Certifique-se: se você adicionou o método sizeForItemAt indexPath, então deve REMOVER o método ...

Remover Método Abaixo

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

}

12
Como isso é útil?
almas,

1
Almas, isso será útil para definir o tamanho de célula personalizado de UICollectionViewCell ... Existem variáveis ​​cellWidth e cellHeight, em que você pode definir seus próprios valores ... Bem como "layout.sectionInset", "layout.minimumLineSpacing" e "layout .minimumInteritemSpacing ", essas variáveis ​​também são importantes para o tamanho de UICollectionViewCell.
Gaurav Rami

2
Isso só funciona se todas as células tiverem o mesmo tamanho. A resposta abaixo é a correta
JeffN

isso é para alterar o tamanho do UICollectionView, mas não da célula dentro da visualização
Async-

Esta não é uma resposta ao motivo pelo qual o método delegado não é chamado
Ziv Kesten

10

Swift 5

Todas essas etapas são necessárias :

  1. Em conformidade com UICollectionViewDelegateFlowLayout <== Absolutamente necessário !!
  2. e para UICollectionViewDelegate, UICollectionViewDataSource
  3. Defina-os em viewDidLoad: collectionView.delegate = selfecollectionView.dataSource = self
  4. Defina o tamanho estimado como nenhum no construtor de interface
  5. Certifique-se de que o método a seguir tenha sizeForItemAt e não sizeForItemAtIndexPath

Como :

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

1
Estimar o tamanho para nenhum - salve o meu dia!
Joe Hallenbeck

6

A primeira classe precisa confirmar para UICollectionViewDelegateFlowLayout. Então você precisa escrever o seguinte código em viewDidLoad ():

// Para dizer ao UICollectionView para usar os métodos UICollectionViewDelegateFlowLayout do seu UIViewController

collectionView.delegate = self

// Se você deseja definir seu próprio layout de fluxo de visualização de coleção

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

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

Usando este método de código UICollectionViewDelegateFlowLayout

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

será chamado, você pode definir o tamanho neste método.


4

Três coisas que você precisa verificar se nenhuma resposta funcionar:

  1. Implemente o Delegado FlowLayout: class MyController: UICollectionViewController, UICollectionViewDelegateFlowLayout

  2. Use o método para o tamanho do item para swift 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. Selecione Estimate size = Noneno elemento Inspecionar de UICollectionView.


2

Eu tive o mesmo problema e nada resolveria. Recebi um aviso amarelo dizendo para torná-lo privado porque se aproximava de outra função definida pelo Delegado de Layout. O que consertou para mim foi:

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

Observe a diferença de "sizeForItemAtIndexPath" para o "sizeForItemAt" correto.

Eu arranquei meu cabelo por dias tentando descobrir isso e finalmente funcionou. Abaixo, incluirei todas as minhas funções para mostrar como também "escondi" uma célula tornando a altura igual a 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

Eu tive esse problema na noite passada. Finalmente resolvi à meia-noite quando percebi que o método 'didSelectItemAtIndex' não estava fechado com um colchete de fechamento "}"

Eu adicionei um colchete de fechamento na parte inferior da classe quando questionado pelo erro de compilação. Portanto, todos os métodos abaixo de 'didSelectItemAtIndex' estavam dentro desse método.

Postando aqui apenas no caso de alguém perder 4 horas de suas noites com este aqui :-(


0

Certifique-se de colocá-lo em viewDidLoad ()

collectionView.delegate = self

0

meu problema era que eu tinha meu objeto UICollectionViewDataSource criado como variável local. Portanto, se você inicializar seu objeto dataSource manualmente no código, certifique-se de armazená-lo como uma variável global.


0

Use este método

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

}

Ao invés de

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

}

-11

Para mim (no Swift 3.1), o método deve ser declarado público assim:

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

Não se esqueça de torná-lo público .


publicé o que você usa para tornar seu código acessível entre estruturas e módulos.
ScottyBlades
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.