UICollectionView міжрядкові поля


181

У мене є UICollectionViewякий показує фотографії. Я створив перегляд колекції за допомогою UICollectionViewFlowLayout. Це працює добре, але я хотів би мати інтервал на полях. Чи можна це зробити, використовуючи UICollectionViewFlowLayoutчи потрібно реалізувати своє UICollectionViewLayout?

Відповіді:


332

Ви можете використовувати collectionView:layout:insetForSectionAtIndex:метод для свого UICollectionViewабо встановити sectionInsetвластивість UICollectionViewFlowLayoutоб'єкта, приєднаного до вашого UICollectionView:

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

або

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

Оновлено для Swift 5

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

35
Мені здається, що ліві та праві вставки не працюють, коли використовується вертикальний макет потоку ...
Джон

1
Тепер переопределення методу sectionInset підкласу UICollectionViewFlowLayout також не робить ефекту. Налаштування властивості, описаної нижче, працює.
Дрен

4
NB: не забудьте додати UICollectionViewDelegateFlowLayoutдо свого списку делегатів ViewController, щоб використовувати методinsetForSectionAtIndex
Девід Дуглас

98

Налаштування вставки в програмі Interface Builder, як показано на скріншоті нижче

Налаштування вставних секцій для UICollectionView

У результаті вийде щось подібне:

Клітина перегляду колекції з вставками секцій


2
Чудова відповідь, я просто хотів зазначити, що вам також доведеться грати з мінімальним інтервалом, щоб вставка секції працювала добре.
Smit Yash

75

Щоб додати інтервал у цілому UICollectionView :

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

Щоб грати з інтервалом між елементами одного рядка (стовпець, якщо ви прокручуєте горизонтально), та їх розмірами:

flow.itemSize = ...;
flow.minimumInteritemSpacing = ...;

5
Це працює, але collection.collectionViewLayoutпотрібен акторський склад, як у прикладі @Pooja: UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) self.collectionViewLayout;
jwj

Кастинг у швидкому станіif let flow = collectionViewLayout as? UICollectionViewFlowLayout { flow.itemSize = CGSize(width: 100, height: 100) }
Емілі

41

Швидкий 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 і швидкий 5

let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout

не працює. Використовуйте нижче роботи.

let flow = UICollectionViewFlowLayout()

введіть тут опис зображення


Чи є спосіб встановити колір на інтервал?
Martín Serrano

1
@ MartínDaniel Просто встановіть backgroundColorз collectionView. Або будь-який супер вид.
Вільям Ху

1
але в краях немає меж
user924

@ user924 Поля на краях можна встановити за допомогою UIEdgeInsets (вгорі: зліва: знизу: праворуч:). Якщо прокручувати вертикально, встановіть ліву / праву вставки. Якщо ви прокручуєте горизонтально, встановіть верхню та нижню вставки.
Марсі

40

Просто для виправлення неправильної інформації на цій сторінці:

1- minimumInteritemSpacing : Мінімальний інтервал для використання між елементами в одному рядку.

Значення за замовчуванням: 10,0.

(Для сітки з вертикальною прокруткою це значення являє собою мінімальний проміжок між елементами в одному рядку.)

2- minimalLineSpacing : Мінімальний інтервал для використання між рядками елементів у сітці.

Посилання: http://developer.apple.com/library/ios/#documentation/uikit/reference/UICollectionViewFlowLayout_class/Reference/Reference.html


2
Це, мабуть, не впливає на проміжки між розділами, лише між елементами в одному розділі?
Crashalot

@Crashalot - ти впевнений, що ти не маєш на увазі minimalLineSpacing? тобто кожна лінія комірок? Існують також варіанти вставки секцій, якщо ви дійсно використовуєте розділи.
Чаккі

Це працювало для мене, роблячи це через інтерфейс розкадровки. Я шукав рішення для горизонтального перегляду лише колекції. Дякую +10
kemicofa ghost

9

Сучасний швидкий, автоматичний розрахунок макета

Хоча ця тема вже містить купу корисних відповідей, я хочу додати сучасну версію Swift , засновану на відповіді Вільяма Ху. Це також покращує дві речі:

  • Відстань між різними рядками тепер завжди буде відповідати інтервалу між елементами в одному рядку.
  • Встановлюючи мінімальну ширину, код автоматично обчислює кількість елементів підряд і застосовує цей стиль до потокового макета.

Ось код:

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

Якщо itemsInOneLine1, то це призведе до NaN через ділення на нуль тут:itemsInOneLine / (itemsInOneLine - 1)
TylerJames

1
@TylerJames Дякую! Я скоригував код, щоб виправити проблему;)
fredpi

8

використання setMinimumLineSpacing:та setMinimumInteritemSpacing:на UICollectionViewFlowLayout-об'єкт.


Ні, це не працює, як очікувалося. setMinimumLineSpacing: Мінімальний інтервал для використання між елементами в одному рядку. І setMinimumInteritemSpacing є: Мінімальний інтервал для використання між рядками елементів у сітці. Моє запитання щодо поля, а не простору між елементами. напр. Зліва і верхній інтервал першого елемента.
Мерт

припускаючи вертикальний srollDirection, ви можете використовувати contentInset для міжряддя першого та останнього рядків. Крім того, ви можете додати свої поля в своїх клітинках.
Джонатан Кішон

8

Використання collectionViewFlowLayout.sectionInsetабо collectionView:layout:insetForSectionAtIndex:правильність.

Однак якщо ваша колекціяView має декілька розділів, і ви хочете додати поле до всього колекціїView, рекомендую використати 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);

5

Для розміщення місця між CollectionItems використовуйте це

записати ці два рядки у viewdidload

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

5

Встановіть insetForSectionAtвластивість UICollectionViewFlowLayoutоб'єкта, приєднаного до вашогоUICollectionView

Обов’язково додайте цей протокол

UICollectionViewDelegateFlowLayout

Швидкий

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

Мета - С

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

2

В 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;

Все, що вам потрібно зробити, це змінити значення itemsPerRow, і воно відповідно оновить кількість елементів у рядку. Крім того, ви можете змінити значення інтервалу, якщо ви хочете більш-менш загальний інтервал.

введіть тут опис зображення введіть тут опис зображення


1
Приємно ... це Work Perfect.
sohil

1

Для додавання поля до вказаних комірок ви можете використовувати цю власну макет потоку. 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
    }
}

0

У swift 4 та autoLayout ви можете використовувати sectionInset так:

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

-1

Щоб додати роздільну здатність 10 пікселів між кожним розділом, просто напишіть це

flowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0,10,0);

при використанні UICollectionReusableView роду UICollectionElementKindSectionFooter ваше рішення не буде працювати
Pratik Jamariya

-1
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {       
         return UIEdgeInsetsMake(7, 10, 5, 10);    
   }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.