Last active
November 11, 2016 17:13
-
-
Save AntonTheDev/5a57eec60b3c0a94821592675dbdebfb to your computer and use it in GitHub Desktop.
Vertical Column Based Flow Layout
This file contains hidden or 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
| class SomeUIViewControllerExample: UIViewController { | |
| override func viewWillAppear(_ animated: Bool) { | |
| super.viewWillAppear(animated) | |
| view.addSubview(collectionView) | |
| collectionView.frame = view.bounds | |
| } | |
| lazy var collectionView : UICollectionView = { | |
| [unowned self] in | |
| let flowLayout = ColumnBasedVerticalLayout() | |
| flowLayout.delegate = self | |
| var collectionView : UICollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout : ColumnBasedVerticalLayout()) | |
| collectionView.clipsToBounds = true | |
| collectionView.showsVerticalScrollIndicator = false | |
| collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell") | |
| collectionView.delegate = self | |
| collectionView.dataSource = self | |
| collectionView.alwaysBounceVertical = true | |
| return collectionView | |
| }() | |
| } | |
| extension SomeUIViewControllerExample : UICollectionViewDelegate, UICollectionViewDataSource, ColumnBasedVerticalLayoutDelegate { | |
| func numberOfSections(in collectionView: UICollectionView) -> Int { | |
| return 1 | |
| } | |
| func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | |
| return 10 | |
| } | |
| func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { | |
| let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) | |
| if indexPath.row == 0 { | |
| cell.backgroundColor = UIColor.blue | |
| } else if indexPath.row == 1 { | |
| cell.backgroundColor = UIColor.red | |
| } else if indexPath.row == 2 { | |
| cell.backgroundColor = UIColor.orange | |
| } else if indexPath.row == 3 { | |
| cell.backgroundColor = UIColor.purple | |
| }else if indexPath.row == 4 { | |
| cell.backgroundColor = UIColor.blue | |
| }else if indexPath.row == 5 { | |
| cell.backgroundColor = UIColor.red | |
| }else if indexPath.row == 6 { | |
| cell.backgroundColor = UIColor.orange | |
| }else if indexPath.row == 7 { | |
| cell.backgroundColor = UIColor.blue | |
| }else if indexPath.row == 8 { | |
| cell.backgroundColor = UIColor.green | |
| }else if indexPath.row == 9 { | |
| cell.backgroundColor = UIColor.brown | |
| }else { | |
| cell.backgroundColor = UIColor.purple | |
| } | |
| return cell | |
| } | |
| func numberOfcolumns(in flowLayout : ColumnBasedVerticalLayout) -> Int { | |
| return 2 | |
| } | |
| func flowLayout(_ flowLayout : ColumnBasedVerticalLayout, sizeForItemAtIndexPath indexPath:NSIndexPath) -> CGSize { | |
| var height = 200.0 | |
| let width = (collectionView.bounds.width / 2.0) | |
| if indexPath.row == 0 { | |
| height = 380.0 | |
| } else if indexPath.row == 1 { | |
| height = 300.0 | |
| } else if indexPath.row == 2 { | |
| height = 300.0 | |
| } else if indexPath.row == 3 { | |
| height = 300.0 | |
| } else if indexPath.row == 4 { | |
| height = 380.0 | |
| } else if indexPath.row == 5 { | |
| height = 300.0 | |
| } else if indexPath.row == 6 { | |
| height = 300.0 | |
| } else if indexPath.row == 7 { | |
| height = 300.0 | |
| } else if indexPath.row == 8 { | |
| height = 300.0 | |
| } else if indexPath.row == 9 { | |
| height = 300.0 | |
| } | |
| return CGSize(width: width, height: CGFloat(height)) | |
| } | |
| } | |
| protocol ColumnBasedVerticalLayoutDelegate : class { | |
| func flowLayout(_ flowLayout : ColumnBasedVerticalLayout, sizeForItemAtIndexPath indexPath:NSIndexPath) -> CGSize | |
| func numberOfcolumns(in flowLayout : ColumnBasedVerticalLayout) -> Int | |
| } | |
| class ColumnBasedVerticalLayout: UICollectionViewFlowLayout { | |
| weak var delegate : ColumnBasedVerticalLayoutDelegate? | |
| fileprivate var attributeCache = [UICollectionViewLayoutAttributes]() | |
| fileprivate var contentHeight:CGFloat = 0.0 | |
| override init() { | |
| super.init() | |
| minimumInteritemSpacing = 0.0 | |
| minimumLineSpacing = 0.0 | |
| sectionInset = UIEdgeInsets.zero | |
| scrollDirection = .vertical | |
| } | |
| required init?(coder aDecoder: NSCoder) { | |
| fatalError("init(coder:) has not been implemented") | |
| } | |
| override func prepare() { | |
| guard let delegate = delegate else { | |
| return | |
| } | |
| let numberOfColumns = delegate.numberOfcolumns(in: self) | |
| let columnWidth = collectionView!.bounds.width / CGFloat(numberOfColumns) | |
| var xOffset = [CGFloat]() | |
| for column in 0 ..< numberOfColumns { | |
| xOffset.append(CGFloat(column) * columnWidth) | |
| } | |
| var column = 0 | |
| var yOffset = [CGFloat](repeating: 0, count: numberOfColumns) | |
| for item in 0 ..< collectionView!.numberOfItems(inSection: 0) { | |
| let indexPath = IndexPath(item: item, section: 0) | |
| let size = delegate.flowLayout(self, sizeForItemAtIndexPath: indexPath as NSIndexPath) | |
| let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) | |
| attributes.frame = CGRect(x: xOffset[column], y: yOffset[column], width: size.width, height: size.height) | |
| attributeCache.append(attributes) | |
| contentHeight = max(contentHeight, attributes.frame.maxY) | |
| yOffset[column] = yOffset[column] + CGFloat(size.height) | |
| if column >= (numberOfColumns - 1) { | |
| column = 0 | |
| } else { | |
| column = column + 1 | |
| } | |
| } | |
| } | |
| override var collectionViewContentSize : CGSize { | |
| return CGSize(width: collectionView!.bounds.width, height: contentHeight) | |
| } | |
| override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { | |
| var layoutAttributes = [UICollectionViewLayoutAttributes]() | |
| for attributes in attributeCache { | |
| if attributes.frame.intersects(rect ) { | |
| layoutAttributes.append(attributes) | |
| } | |
| } | |
| return layoutAttributes | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment