UICollectionView margens de espaçamento


181

Eu tenho um UICollectionViewque mostra fotos. Eu criei a coleção usando UICollectionViewFlowLayout. Funciona bem, mas eu gostaria de ter espaçamento nas margens. É possível fazer isso usando UICollectionViewFlowLayoutou devo implementar o meu UICollectionViewLayout?

Respostas:


333

Você pode usar o collectionView:layout:insetForSectionAtIndex:método para você UICollectionViewou definir a sectionInsetpropriedade do UICollectionViewFlowLayoutobjeto anexado ao seu UICollectionView:

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

ou

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

Atualizado para o Swift 5

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

35
Parece que não estou conseguindo inserir as setas esquerda e direita para trabalhar ao usar um layout de fluxo vertical ... #
— John

1
Agora, substituir o método sectionInset de UICollectionViewFlowLayout subclassed também não tem efeito. A propriedade de configuração descrita abaixo funciona.
— Dren 29/04

4
NB: lembre-se de adicionar UICollectionViewDelegateFlowLayoutà sua lista de delegados viewcontroller usar o métodoinsetForSectionAtIndex
— David Douglas

98

Configurando inserções no Interface Builder, como mostrado na captura de tela abaixo

Definindo inserções de seção para UICollectionView

Irá resultar em algo como isto:

Uma célula de exibição de coleção com inserções de seção


2
Ótima resposta, só queria ressaltar que você também terá que jogar com espaçamento mínimo para que a seção de seção funcione bem.
— Smit Yash

75

Para adicionar espaçamento no todo UICollectionView :

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

Para brincar com o espaçamento entre elementos da mesma linha (coluna se você estiver rolando horizontalmente) e seus tamanhos:

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

5
Isso funciona, mas as collection.collectionViewLayoutnecessidades de um elenco como no exemplo por @Pooja: UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) self.collectionViewLayout;
— JWJ

Fundição em swiftif let flow = collectionViewLayout as? UICollectionViewFlowLayout { flow.itemSize = CGSize(width: 100, height: 100) }
— emily

41

Swift 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 e swift 5

let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout

não funciona Use abaixo obras.

let flow = UICollectionViewFlowLayout()

insira a descrição da imagem aqui


Existe uma maneira de definir a cor para o espaçamento?
— Martín Serrano

1
@ MartínDaniel Basta definir o backgroundColordo collectionView. Ou qualquer que seja a super visão.
— William Hu

1
mas não há margens nas bordas
— user924

@ user924 As margens nas arestas podem ser definidas com UIEdgeInsets (superior: esquerda: inferior: direita:). Se rolar verticalmente, defina as inserções esquerda / direita. Se estiver rolando horizontalmente, defina as inserções superior e inferior.
— Marcy

40

Apenas para corrigir algumas informações erradas nesta página:

1- minimumInteritemSpacing : o espaçamento mínimo a ser usado entre os itens na mesma linha.

O valor padrão: 10.0.

(Para uma grade de rolagem vertical, esse valor representa o espaçamento mínimo entre os itens na mesma linha.)

2- minimumLineSpacing : o espaçamento mínimo a ser usado entre linhas de itens na grade.

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


2
Isso não parece afetar o espaçamento entre as seções, apenas entre itens dentro da mesma seção?
— Crashalot 18/01/16

@Crashalot - você tem certeza que não quer dizer minimumLineSpacing? ou seja, cada linha de células? Também há opções para Insertos de Seção, se você realmente estiver usando seções.
— Chucky

Isso funcionou para mim através da interface do storyboard. Eu estava procurando uma solução para visualizações de coleção horizontais apenas. Obrigado +10
— kemicofa ghost

9

Cálculo de layout automático rápido e moderno

Embora esse tópico já contenha várias respostas úteis, quero adicionar uma versão Swift moderna , com base na resposta de William Hu. Também melhora duas coisas:

  • O espaçamento entre linhas diferentes agora sempre corresponderá ao espaçamento entre itens na mesma linha.
  • Ao definir uma largura mínima, o código calcula automaticamente o número de itens em uma linha e aplica esse estilo ao layout do fluxo.

Aqui está o código:

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

Se itemsInOneLinefor 1, isso resultará em um NaN devido à divisão por zero aqui:itemsInOneLine / (itemsInOneLine - 1)
— TylerJames

1
@TylerJames Thanks! Eu ajustei o código para corrigir o problema;)
— fredpi 05/02

8

use setMinimumLineSpacing:e setMinimumInteritemSpacing:no UICollectionViewFlowLayout-Object.


Não, não funciona, como esperado. setMinimumLineSpacing é: O espaçamento mínimo a ser usado entre itens na mesma linha. E setMinimumInteritemSpacing é: O espaçamento mínimo a ser usado entre as linhas de itens na grade. Minha pergunta é sobre margens, não espaço entre elementos. por exemplo. Espaçamento esquerdo e superior do primeiro elemento.
— Mert

assumindo um srollDirection vertical, você pode usar contentInset para espaçamento superior e inferior da primeira e da última linha. Além disso, você pode adicionar suas margens em suas células.
— precisa

8

Usando collectionViewFlowLayout.sectionInsetou collectionView:layout:insetForSectionAtIndex:está correto.

No entanto, se o seu collectionView tiver várias seções e você desejar adicionar margem a todo o collectionView, recomendo usar o 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

Para colocar espaço entre CollectionItems, use este

escreva estas duas linhas em viewdidload

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

5

Defina a insetForSectionAtpropriedade do UICollectionViewFlowLayoutobjeto anexado ao seuUICollectionView

Certifique-se de adicionar este protocolo

UICollectionViewDelegateFlowLayout

Rápido

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

Objetivo - C

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

2

No Objetivo-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;

Tudo o que você precisa fazer é alterar o valor itemsPerRow e ele atualizará o número de itens por linha de acordo. Além disso, você pode alterar o valor do espaçamento, se desejar um espaçamento mais ou menos geral.

insira a descrição da imagem aqui insira a descrição da imagem aqui


1
Bom ... é um trabalho perfeito.
— sohil 16/02

1

Para adicionar margens às células especificadas, você pode usar esse layout de fluxo personalizado. 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

No swift 4 e no autoLayout, você pode usar o sectionInset assim:

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

Para adicionar uma separação de 10 px entre cada seção, basta escrever este

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

quando se utiliza UICollectionReusableView de tipo UICollectionElementKindSectionFooter, sua solução não vai funcionar
— Pratik Jamariya

-1
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {       
         return UIEdgeInsetsMake(7, 10, 5, 10);    
   }
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.