Last active
June 2, 2021 14:11
-
-
Save AnuragMishra/0a694dfa9be1a5eab9fc7368b69812ad to your computer and use it in GitHub Desktop.
Playground for http://stackoverflow.com/questions/41091177/swift-3-how-to-center-horizontally-the-last-row-of-cells-in-a-uicollectionview
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: Playground - noun: a place where people can play | |
import UIKit | |
import PlaygroundSupport | |
class LastRowCenteredLayout: UICollectionViewFlowLayout { | |
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { | |
guard let originalAttributes = super.layoutAttributesForElements(in: rect) else { return nil } | |
guard originalAttributes.isEmpty == false else { return originalAttributes } | |
let finalAttributes = originalAttributes.map { $0.copy() as! UICollectionViewLayoutAttributes } | |
// Find maxY among all element attributes, then all elements line up with that maxY. Those elements are the ones from the last row | |
let maxY = finalAttributes.max { $0.frame.maxY < $1.frame.maxY }?.frame.maxY | |
let lastRowAttrs = finalAttributes.filter { $0.frame.maxY == maxY } | |
// If the elements in the last row don't sit flush against the right edge, then they need to be centered by shifting them a little to the right | |
if lastRowAttrs.frame.maxX < insettedFrame.maxX { | |
let shift = (insettedFrame.maxX - lastRowAttrs.frame.maxX) / 2.0 | |
for attrs in lastRowAttrs { | |
attrs.frame = attrs.frame.offsetBy(dx: shift, dy: 0) | |
} | |
} | |
return finalAttributes | |
} | |
} | |
public class DataSource: NSObject, UICollectionViewDataSource { | |
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | |
return 32; | |
} | |
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { | |
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) | |
cell.backgroundColor = UIColor.green | |
return cell | |
} | |
} | |
extension CGRect { | |
func insettedBy(insets: UIEdgeInsets) -> CGRect { | |
return UIEdgeInsetsInsetRect(self, insets) | |
} | |
} | |
extension Array where Element: UICollectionViewLayoutAttributes { | |
var frame: CGRect { | |
return map { $0.frame }.reduce(self[0].frame, { $0.union($1) }) | |
} | |
} | |
extension UICollectionViewFlowLayout { | |
var insettedFrame: CGRect { | |
guard let frame = collectionView?.frame else { return .zero } | |
return frame.insettedBy(insets: sectionInset) | |
} | |
} | |
let screen = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 500)) | |
screen.backgroundColor = UIColor.white | |
let l = LastRowCenteredLayout() | |
l.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) | |
l.itemSize = CGSize(width: 30, height: 30) | |
let c = UICollectionView(frame: screen.bounds, collectionViewLayout: l) | |
c.backgroundColor = UIColor.blue | |
c.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell") | |
let ds = DataSource() | |
c.dataSource = ds | |
screen.addSubview(c) | |
PlaygroundPage.current.needsIndefiniteExecution = true | |
PlaygroundPage.current.liveView = screen |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment