Skip to content

Instantly share code, notes, and snippets.

@tbxark
Created August 21, 2017 04:29
Show Gist options
  • Select an option

  • Save tbxark/f234f3a91f68be55f81d30efa41fe736 to your computer and use it in GitHub Desktop.

Select an option

Save tbxark/f234f3a91f68be55f81d30efa41fe736 to your computer and use it in GitHub Desktop.
CenterAlignmentFlowLayout
//
// CenterAlignmentFlowLayout.swift
// Play
//
// Created by Tbxark on 15/12/28.
// Copyright © 2015年 TBXark. All rights reserved.
//
import UIKit
class CenterAlignmentFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let superAttributes = super.layoutAttributesForElements(in: rect) else {
return nil
}
var rowCollections = [CGFloat: [UICollectionViewLayoutAttributes]]()
let flowDelegate = collectionView?.delegate as? UICollectionViewDelegateFlowLayout
let delegateSupportsInteritemSpacing = flowDelegate?.responds(to: #selector(UICollectionViewDelegateFlowLayout.collectionView(_:layout:minimumInteritemSpacingForSectionAt:))) ?? false
for itemAttributes in superAttributes {
let midYRound = CGFloat(roundf(Float(itemAttributes.frame.midY)))
let midYPlus = midYRound + 1
let midYMinus = midYRound - 1
var key: CGFloat? = nil
if rowCollections.keys.contains(midYPlus) {
key = midYPlus
}
if rowCollections.keys.contains(midYMinus) {
key = midYMinus
}
let realKey = key ?? midYMinus
if !rowCollections.keys.contains(realKey) {
rowCollections[realKey] = [UICollectionViewLayoutAttributes]()
}
rowCollections[realKey]?.append(itemAttributes)
}
guard let collection = collectionView else {
return nil
}
let collectionViewWidth: CGFloat = collection.bounds.width - collection.contentInset.left - collection.contentInset.right
for (_, itemAttributesCollection) in rowCollections {
let itemsInRow = itemAttributesCollection.count
var interitemSpacing = minimumInteritemSpacing
if delegateSupportsInteritemSpacing && itemsInRow > 0 {
let section = (itemAttributesCollection[0].indexPath as NSIndexPath).section
if let temp = flowDelegate?.collectionView?(collection, layout: self, minimumInteritemSpacingForSectionAt: section) {
interitemSpacing = temp
}
}
let aggregateInteritemSpacing = interitemSpacing * CGFloat(itemsInRow - 1)
var aggregateItemWidths: CGFloat = 0
for itemAttributes in itemAttributesCollection {
aggregateItemWidths += itemAttributes.frame.width
}
let alignmentWidth = aggregateItemWidths + aggregateInteritemSpacing
let alignmentXOffset = (collectionViewWidth - alignmentWidth) / 2
var previousFrame: CGRect = CGRect.zero
for itemAttributes in itemAttributesCollection {
var itemFrame: CGRect = itemAttributes.frame
if previousFrame.equalTo(CGRect.zero) {
itemFrame.origin.x = alignmentXOffset
} else {
itemFrame.origin.x = previousFrame.maxX + interitemSpacing
}
itemAttributes.frame = itemFrame
previousFrame = itemFrame
}
}
return superAttributes
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment