J'ai un UICollectionView
qui montre des photos. J'ai créé la collectionview en utilisant UICollectionViewFlowLayout
. Cela fonctionne bien mais j'aimerais avoir un espacement sur les marges. Est-il possible de faire cela en utilisant UICollectionViewFlowLayout
ou dois-je implémenter ma propre UICollectionViewLayout
?
Vous pouvez utiliser la méthode collectionView:layout:insetForSectionAtIndex:
pour votre UICollectionView
ou définir la propriété sectionInset
de l'objet UICollectionViewFlowLayout
attaché à votre 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)];
Configuration des encarts dans Interface Builder comme indiqué dans la capture d'écran ci-dessous
Résultera en quelque chose comme ceci:
Pour ajouter un espacement sur le entier UICollectionView
:
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) collection.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(topMargin, left, bottom, right);
Pour jouer avec les éléments spacing between de la même ligne (colonne si vous faites défiler horizontalement), et leurs tailles:
flow.itemSize = ...;
flow.minimumInteritemSpacing = ...;
Juste pour corriger certaines informations erronées sur cette page:
1- minimumInteritemSpacing: L'espacement minimal à utiliser entre les éléments de la même ligne.
La valeur par défaut: 10.0.
(Pour une grille à défilement vertical, cette valeur représente l'espacement minimal entre les éléments d'une même ligne.)
2- minimumLineSpacing: L'espacement minimal à utiliser entre les lignes d'éléments dans la grille.
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 = UIEdgeInsetsMake(0, 0, 0, 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
utilisez setMinimumLineSpacing:
et setMinimumInteritemSpacing:
sur l'objet UICollectionViewFlowLayout
-.
Bien que ce fil de discussion contienne déjà de nombreuses réponses utiles, je souhaite ajouter une version moderne de Swift basée sur la réponse de William Hu. Il améliore également deux choses:
Voici le code:
// 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 / (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)
Pour mettre un espace entre CollectionItem
s, utilisez ceci
écrit ces deux lignes dans viewdidload
UICollectionViewFlowLayout *collectionViewLayout = (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
collectionViewLayout.sectionInset = UIEdgeInsetsMake(<CGFloat top>, <CGFloat left>, <CGFloat bottom>, <CGFloat right>)
Utiliser collectionViewFlowLayout.sectionInset
ou collectionView:layout:insetForSectionAtIndex:
est correct.
Cependant, si votre collectionView comporte plusieurs sections et que vous souhaitez ajouter une marge à l'ensemble de la collectionView, il est recommandé d'utiliser le 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);
Pour ajouter des marges à des cellules spécifiées, vous pouvez utiliser cette présentation de flux personnalisée . 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
}
}
En 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;
Tout ce que vous avez à faire est de changer la valeur de itemsPerRow et le nombre d'éléments par ligne sera mis à jour en conséquence. De plus, vous pouvez modifier la valeur d'espacement si vous souhaitez un espacement plus ou moins général.
Définissez la propriété insetForSectionAt
de l'objet UICollectionViewFlowLayout
attaché à votre UICollectionView
Assurez-vous d'ajouter ce protocole
UICollectionViewDelegateFlowLayout
Rapide
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets (top: top, left: left, bottom: bottom, right: right)
}
Objectif c
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(top, left, bottom, right);
}
Dans Swift 4 et autoLayout, vous pouvez utiliser sectionInset comme ceci:
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