CollectionView sizeForItemAtIndexPath tidak pernah dipanggil

96

Ini membuatku gila! Saya memiliki UICollectionViewController seperti yang ditunjukkan di bawah ini:

class PhrasesCompactCollectionViewController: UICollectionViewController

NumberOfSections dan cellForItemAt dipanggil tetapi sizeForItemAtIndexPath tidak pernah dipanggil. Saya menggunakan kode yang sama persis di tempat lain dan itu diaktifkan dengan benar. Saya menggunakan Xcode 8 Beta 6.

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

        return CGSize(width: 120, height:120) 
    }
john doe
sumber

Jawaban:

255

Anda perlu menentukan bahwa Anda mengimplementasikan protokol UICollectionViewDelegateFlowLayoutdalam deklarasi kelas Anda.

class PhrasesCompactCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout

almas
sumber
11
Saya melakukan ini tetapi masih belum dipanggil. :(
Van Du Tran
58

Di Swift 3+ Gunakan metode ini:

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

Pastikan kelas Anda mematuhi kedua Delegasi

  • UICollectionViewDelegate

  • UICollectionViewDelegateFlowLayout

Shiv Kumar
sumber
4
Ini berlebihan untuk dipatuhi UICollectionViewDelegateseperti yang sudah dilakukan UICollectionViewController.
Van Du Tran
3
@VanDuTran Tidak berlebihan untuk menyatakan bahwa itu diperlukan karena menjadi UICollectionViewController tidak diperlukan ...
Michael Hudson
Saya pikir yang Anda maksud adalah bahwa tampilan non koleksi, Viewcontroller dapat menjadi UICollectionViewDelegate.
ScottyBlades
1
UICollectionViewDelegateFlowLayout mewarisi dari UICollectionViewDelegate jadi cukup terapkan UICollectionViewDelegateFlowLayout
evya
49

Saya memiliki masalah yang sama. Satu hal yang membantu saya adalah membuat 'Estimated Size' untuk Cell Size di bawah collectionView size inspector 'None'.

masukkan deskripsi gambar di sini

Zenman C
sumber
9
Anda menyelamatkan teman hari saya, Anda adalah pahlawan
Asif Ali
1
Entah bagaimana semua jawaban lain di semua posting lain tentang penggunaan sizeForItemAtgagal menyebutkan ini. Sangat berguna.
JCutting8
Ini gila!!!! Saya menguji simulator iPhone 5 dengan versi iOS 10.3.1 dan metode dipanggil. pada simulator iPhone 5 dengan metode versi 10.3.1 tidak dipanggil !!! Saya mengubah Estimate Size menjadi None. Ini mulai dipanggil di iPhone 5s. WT WT WT
hasan
Terima kasih banyak! Tampilan koleksi saya dengan kustom sizeForItemAtberfungsi dengan baik hingga Xcode 11.4 ketika tiba-tiba selnya salah lebar. Mencoba banyak hal dan ini akhirnya berhasil.
Filip
Anda menghemat waktu saya. Terima kasih banyak.
Shahbaz Akram
17

Cepat 5

Semua langkah ini diperlukan :

  1. Sesuai dengan UICollectionViewDelegateFlowLayout <== Benar-benar dibutuhkan !!
  2. dan untuk UICollectionViewDelegate, UICollectionViewDataSource
  3. Setel ini di viewDidLoad: collectionView.delegate = selfdancollectionView.dataSource = self
  4. Setel Estimate Size ke None di Interface Builder
  5. Pastikan metode berikut memiliki sizeForItemAt dan bukan sizeForItemAtIndexPath

sebagai :

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
    return CGSize(width: 100, height:100)
} 
Xys
sumber
3
Perkirakan Ukuran ke Tidak Ada - simpan hari saya!
Joe Hallenbeck
Terima jawaban ini, itu benar!
NickCoder
15

Cepat 3

Untuk mengatur Ukuran Sel UICollectionView, Anda perlu membuat dan menyesuaikan objek UICollectionViewFlowLayout. Sesuaikan properti dan setel objek layout itu ke objek UICollectionView.

Ubah objek cellheight dan cellWidth sesuai dengan kebutuhan Anda (sel tinggi dan lebar yang Anda inginkan).

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

Pastikan: jika Anda menambahkan metode sizeForItemAt indexPath maka harus HAPUS metode ...

Hapus Metode Di Bawah Ini

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

}
Gaurav Rami
sumber
12
Bagaimana ini membantu?
almas
1
Almas, Ini akan membantu untuk mengatur ukuran sel khusus UICollectionViewCell ... Ada variabel cellWidth dan cellHeight, di mana Anda dapat menentukan nilai Anda sendiri ... Serta "layout.sectionInset", "layout.minimumLineSpacing" dan "layout .minimumInteritemSpacing ", variabel ini juga penting untuk ukuran UICollectionViewCell ..
Gaurav Rami
2
Ini hanya berfungsi jika semua sel memiliki ukuran yang sama. Jawaban di bawah ini adalah jawaban yang benar
JeffN
ini untuk mengubah ukuran UICollectionView tetapi bukan sel di dalam tampilan
Async-
Ini bukan jawaban mengapa metode delegasi tidak dipanggil
Ziv Kesten
6

Kelas pertama perlu mengonfirmasi ke UICollectionViewDelegateFlowLayout. Kemudian Anda perlu menulis kode berikut di viewDidLoad ():

// Untuk memberi tahu UICollectionView agar menggunakan metode UIViewController UICollectionViewDelegateFlowLayout Anda

collectionView.delegate = self

// Jika Anda ingin menyetel tata letak aliran tampilan koleksi Anda sendiri

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

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

Dengan menggunakan kode ini metode UICollectionViewDelegateFlowLayout

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

akan dipanggil, Anda dapat mengatur ukuran dalam metode ini.

Program HS
sumber
4

Tiga hal yang perlu Anda periksa jika tidak ada jawaban yang berhasil:

  1. Menerapkan Delegasi FlowLayout: class MyController: UICollectionViewController, UICollectionViewDelegateFlowLayout

  2. Gunakan metode ukuran item untuk 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. Pilih Estimate size = Nonedi elemen Inspect dari UICollectionView.

Manish
sumber
2

Saya memiliki masalah yang sama dan tidak ada yang dapat memperbaikinya. Saya mendapat peringatan kuning yang mengatakan untuk membuatnya pribadi karena itu mendekati fungsi lain yang ditentukan oleh Delegasi Tata Letak. Yang memperbaikinya untuk saya adalah:

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

Perhatikan perbedaan dari "sizeForItemAtIndexPath" ke "sizeForItemAt" yang benar.

Saya merobek rambut saya selama berhari-hari mencoba mencari tahu dan akhirnya berhasil. Di bawah ini saya akan menyertakan semua fungsi saya untuk menunjukkan kepada Anda bagaimana saya juga "menyembunyikan" sel dengan membuat tingginya sama dengan 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)
    }
}
Stephen Rains
sumber
1

Pastikan Anda meletakkan ini di viewDidLoad ()

collectionView.delegate = self
Azam
sumber
0

Saya mengalami masalah ini tadi malam. Akhirnya menyelesaikannya pada tengah malam ketika saya menyadari metode 'didSelectItemAtIndex' tidak ditutup dengan braket penutupan "}"

Saya menambahkan braket penutup di bagian paling bawah kelas ketika ditanya oleh kesalahan kompilasi. Jadi pada dasarnya semua metode di bawah 'didSelectItemAtIndex' ada di dalam metode itu.

Posting di sini untuk berjaga-jaga kalau-kalau ada orang lain yang menyia-nyiakan 4 jam malam mereka untuk yang satu ini :-(

Charlie Seligman
sumber
0

masalah saya adalah bahwa saya membuat objek UICollectionViewDataSource saya sebagai variabel lokal. Jadi, jika Anda menginisialisasi objek dataSource secara manual dalam kode, pastikan untuk menyimpannya sebagai variabel global.

Petro Darchyn
sumber
0

Gunakan metode ini

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

}

Dari pada

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

}
Abdul Malik Aman
sumber
0

Cukup tambahkan: UICollectionViewDelegateFlowLayout

class YourClass: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {}
Muzammil
sumber
-12

Bagi saya (di Swift 3.1) metode tersebut harus diumumkan ke publik seperti ini:

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

Jangan lupa untuk mempublikasikannya .

Oliver Eichhorn
sumber
publicadalah apa yang Anda gunakan untuk membuat kode Anda dapat diakses antara kerangka kerja dan modul.
ScottyBlades