Margin spasi UICollectionView

181

Saya punya UICollectionViewyang menunjukkan foto. Saya telah membuat tampilan koleksi menggunakan UICollectionViewFlowLayout. Ini berfungsi baik tetapi saya ingin memiliki jarak pada margin. Apakah mungkin untuk melakukan itu menggunakan UICollectionViewFlowLayoutatau saya harus menerapkan sendiri UICollectionViewLayout?

Mert
sumber

Jawaban:

333

Anda dapat menggunakan collectionView:layout:insetForSectionAtIndex:metode ini untuk UICollectionViewatau menyetel sectionInsetproperti UICollectionViewFlowLayoutobjek yang dilampirkan ke UICollectionView:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsMake(top, left, bottom, right);
}

atau

UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[aFlowLayout setSectionInset:UIEdgeInsetsMake(top, left, bottom, right)];

Diperbarui untuk Swift 5

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
       return UIEdgeInsets(top: 25, left: 15, bottom: 0, right: 5)
    }
michael23
sumber
35
Saya sepertinya tidak akan mendapatkan insets kiri dan kanan untuk bekerja ketika menggunakan tata letak aliran vertikal ...
John
1
Sekarang menimpa metode sectionInset dari UICollectionViewFlowLayout subkelas juga tidak memiliki efek. Pengaturan properti yang dijelaskan di bawah ini berfungsi.
Dren
4
NB: jangan lupa menambahkan UICollectionViewDelegateFlowLayoutdaftar delegasi ViewController Anda untuk menggunakan metode iniinsetForSectionAtIndex
David Douglas
98

Menyiapkan insets di Interface Builder seperti yang ditunjukkan pada gambar di bawah

Mengatur insets bagian untuk UICollectionView

Akan menghasilkan sesuatu seperti ini:

Sel tampilan koleksi dengan insets bagian

krzymar
sumber
2
Jawaban yang bagus, hanya ingin menunjukkan bahwa Anda juga harus bermain dengan jarak minimum sehingga inset bagian berfungsi dengan baik.
Smit Yash
75

Untuk menambahkan spasi pada keseluruhan UICollectionView :

UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) collection.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(topMargin, left, bottom, right);

Untuk bermain dengan spasi antara elemen-elemen dari baris yang sama (kolom jika Anda menggulir secara horizontal), dan ukurannya:

flow.itemSize = ...;
flow.minimumInteritemSpacing = ...;
marmor
sumber
5
Ini berfungsi, tetapi collection.collectionViewLayoutkebutuhan pemain seperti dalam contoh oleh @Pooja: UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) self.collectionViewLayout;
jwj
Casting dengan cepatif let flow = collectionViewLayout as? UICollectionViewFlowLayout { flow.itemSize = CGSize(width: 100, height: 100) }
emily
41

Cepat 4

    let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout // If you create collectionView programmatically then just create this flow by UICollectionViewFlowLayout() and init a collectionView by this flow.

    let itemSpacing: CGFloat = 3
    let itemsInOneLine: CGFloat = 3
    flow.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    let width = UIScreen.main.bounds.size.width - itemSpacing * CGFloat(itemsInOneLine - 1) //collectionView.frame.width is the same as  UIScreen.main.bounds.size.width here.
    flow.itemSize = CGSize(width: floor(width/itemsInOneLine), height: width/itemsInOneLine)
    flow.minimumInteritemSpacing = 3
    flow.minimumLineSpacing = 3

EDIT XCode 11.4 dan cepat 5

let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout

tidak bekerja Gunakan karya di bawah ini.

let flow = UICollectionViewFlowLayout()

masukkan deskripsi gambar di sini

William Hu
sumber
Apakah ada cara untuk mengatur warna ke spasi?
Martín Serrano
1
@ MartínDaniel Hanya mengatur backgroundColordari collectionView. Atau apa pun tampilan supernya.
William Hu
1
tetapi tidak ada margin di tepian
user924
@ user924 Margin di tepian dapat diatur dengan UIEdgeInsets (atas: kiri: bawah: kanan:). Jika menggulir secara vertikal, atur inset kiri / kanan. Jika menggulir secara horizontal, atur inset atas dan bawah.
Marcy
40

Hanya untuk memperbaiki beberapa informasi yang salah di halaman ini:

1- minimumInteritemSpacing : Jarak minimum untuk digunakan di antara item dalam baris yang sama.

Nilai default: 10.0.

(Untuk kisi gulir vertikal, nilai ini menunjukkan jarak minimum antara item dalam baris yang sama.)

2- minimumLineSpacing : Jarak minimum untuk digunakan di antara baris item dalam kisi.

Ref: http://developer.apple.com/library/ios/#documentation/uikit/reference/UICollectionViewFlowLayout_class/Reference/Reference.html

Felix
sumber
2
Ini sepertinya tidak memengaruhi jarak antar bagian, hanya antar item dalam bagian yang sama?
Crashalot
@ Crashalot - Anda yakin tidak bermaksud minimumLineSpacing? yaitu setiap baris sel? Ada juga opsi untuk Bagian Insets jika Anda benar-benar menggunakan bagian.
Chucky
Ini berhasil bagi saya melakukannya melalui antarmuka storyboard. Saya sedang mencari solusi untuk tampilan koleksi hanya horisontal. Terima kasih +10
hantu kemicofa
9

Modern Swift, Perhitungan Tata Letak Otomatis

Sementara utas ini sudah berisi banyak jawaban yang bermanfaat, saya ingin menambahkan versi Swift modern , berdasarkan jawaban William Hu. Ini juga meningkatkan dua hal:

  • Jarak antar baris yang berbeda sekarang akan selalu cocok dengan jarak antar item di baris yang sama.
  • Dengan menetapkan lebar minimum, kode secara otomatis menghitung jumlah item dalam satu baris dan menerapkan gaya itu ke tata letak aliran.

Berikut kodenya:

// Create flow layout
let flow = UICollectionViewFlowLayout()

// Define layout constants
let itemSpacing: CGFloat = 1
let minimumCellWidth: CGFloat = 120
let collectionViewWidth = collectionView!.bounds.size.width

// Calculate other required constants
let itemsInOneLine = CGFloat(Int((collectionViewWidth - CGFloat(Int(collectionViewWidth / minimumCellWidth) - 1) * itemSpacing) / minimumCellWidth))
let width = collectionViewWidth - itemSpacing * (itemsInOneLine - 1)
let cellWidth = floor(width / itemsInOneLine)
let realItemSpacing = itemSpacing + (width / itemsInOneLine - cellWidth) * itemsInOneLine / max(1, itemsInOneLine - 1))

// Apply values
flow.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
flow.itemSize = CGSize(width: cellWidth, height: cellWidth)
flow.minimumInteritemSpacing = realItemSpacing
flow.minimumLineSpacing = realItemSpacing

// Apply flow layout
collectionView?.setCollectionViewLayout(flow, animated: false)
fredpi
sumber
Jika itemsInOneLine1 maka ini akan menghasilkan NaN karena membaginya dengan nol di sini:itemsInOneLine / (itemsInOneLine - 1)
TylerJames
1
@TylerJames Terima kasih! Saya menyesuaikan kode untuk memperbaiki masalah;)
fredpi
8

gunakan setMinimumLineSpacing:dan setMinimumInteritemSpacing:pada UICollectionViewFlowLayout-Object.

Jonathan Cichon
sumber
Tidak itu tidak berfungsi, seperti yang diharapkan. setMinimumLineSpacing adalah: Spasi minimum untuk digunakan antara item dalam baris yang sama. Dan setMinimumInteritemSpacing adalah: Spasi minimum untuk digunakan di antara baris item dalam kisi. Pertanyaan saya adalah tentang margin bukan ruang antar elemen. misalnya. Spasi pertama dan kiri elemen pertama.
Mert
dengan asumsi srollDirection vertikal Anda dapat menggunakan contentInset untuk spasi atas dan bawah dari baris pertama dan terakhir. Anda juga bisa menambahkan margin Anda di Sel Anda.
Jonathan Cichon
8

Menggunakan collectionViewFlowLayout.sectionInsetatau collectionView:layout:insetForSectionAtIndex:benar.

Namun, jika collectionView Anda memiliki beberapa bagian dan Anda ingin menambahkan margin ke seluruh collectionView, saya sarankan untuk menggunakan scrollView contentInset:

UIEdgeInsets collectionViewInsets = UIEdgeInsetsMake(50.0, 0.0, 30.0, 0.0);
self.collectionView.contentInset = collectionViewInsets;
self.collectionView.scrollIndicatorInsets = UIEdgeInsetsMake(collectionViewInsets.top, 0, collectionViewInsets.bottom, 0);
vmeyer
sumber
5

Untuk menempatkan spasi di antara CollectionItems gunakan ini

tulis dua Baris ini di viewdidload

UICollectionViewFlowLayout *collectionViewLayout = (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
collectionViewLayout.sectionInset = UIEdgeInsetsMake(<CGFloat top>, <CGFloat left>, <CGFloat bottom>, <CGFloat right>)
Pooja Jalan
sumber
5

Setel insetForSectionAtproperti UICollectionViewFlowLayoutobjek yang dilampirkan pada AndaUICollectionView

Pastikan untuk menambahkan protokol ini

UICollectionViewDelegateFlowLayout

Cepat

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

Tujuan - C

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsMake(top, left, bottom, right);
}
PinkeshGjr
sumber
2

Dalam Objective-C

CGFloat spacing = 5;
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*)_habbitCollectionV.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(0, spacing, 0, spacing);
CGFloat itemsPerRow = 2;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat oneMore = itemsPerRow + 1;
CGFloat width = screenRect.size.width - spacing * oneMore;
CGFloat height = width / itemsPerRow;

flow.itemSize = CGSizeMake(floor(height), height);
flow.minimumInteritemSpacing = spacing;
flow.minimumLineSpacing = spacing;

Yang harus Anda lakukan adalah mengubah nilai itemsPerRow dan itu akan memperbarui jumlah item per baris yang sesuai. Selanjutnya, Anda dapat mengubah nilai spasi jika Anda ingin lebih atau kurang spasi umum.

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

ScottyBlades
sumber
1
Bagus ... ini Bekerja Sempurna.
sohil
1

Untuk menambahkan margin ke sel tertentu, Anda dapat menggunakan tata letak aliran kustom ini. https://github.com/voyages-sncf-technologies/VSCollectionViewCellInsetFlowLayout/

extension ViewController : VSCollectionViewDelegateCellInsetFlowLayout 
{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForItemAt indexPath: IndexPath) -> UIEdgeInsets {
        if indexPath.item == 0 {
            return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
        }
        return UIEdgeInsets.zero
    }
}
Myrddin
sumber
0

Di swift 4 dan autoLayout, Anda bisa menggunakan sectionInset seperti ini:

let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        layout.itemSize = CGSize(width: (view.frame.width-40)/2, height: (view.frame.width40)/2) // item size
        layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10) // here you can add space to 4 side of item
        collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout) // set layout to item
        collectionView?.register(ProductCategoryCell.self, forCellWithReuseIdentifier: cellIdentifier) // registerCell
        collectionView?.backgroundColor = .white // background color of UICollectionView
        view.addSubview(collectionView!) // add UICollectionView to view
Mohsen mokhtari
sumber
-1

Untuk menambahkan pemisahan 10px antara setiap bagian tulis saja ini

flowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0,10,0);
Gal Blank
sumber
saat menggunakan UICollectionReusableView dari jenis UICollectionElementKindSectionFooter, solusi Anda tidak akan berfungsi
Pratik Jamariya
-1
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {       
         return UIEdgeInsetsMake(7, 10, 5, 10);    
   }
vishal
sumber