2023-12-19 15:17:30 +00:00
/*
* Copyright ( c ) Meta Platforms , Inc . and affiliates .
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree .
*/
import IGListKit
import UIKit
// / E n a b l e s S e c t i o n C o n t r o l l e r s t o r e t u r n t h e i r o w n l a y o u t . I n t h e f u t u r e , w e m i g h t w a n t I G L i s t K i t
// / t o h a n d l e t h i s , b u t f o r n o w , l e t s k e e p i t s i m p l e .
protocol CompositionLayoutCapable {
func collectionViewSectionLayout ( layoutEnvironment : NSCollectionLayoutEnvironment ) -> NSCollectionLayoutSection ?
}
// / L i k e M i x e d D a t a V i e w C o n t r o l l e r , b u t u s i n g U I C o l l e c t i o n V i e w C o m p o s i t i o n a l L a y o u t
final class CompositionLayoutViewController : UIViewController , ListAdapterDataSource {
private var collectionView : UICollectionView ?
private lazy var adapter : ListAdapter = {
return ListAdapter ( updater : ListAdapterUpdater ( ) , viewController : self )
} ( )
private let data : [ Any ] = [
2025-03-19 17:14:23 +00:00
ActivityItem ( bodyText : " Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " , header : " Activity Start " ) ,
ActivityItem ( bodyText : " Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore. " ) ,
ActivityItem ( bodyText : " Excepteur sint occaecat cupidatat non proident. " ) ,
ActivityItem ( bodyText : " Dominus " , footer : " Activity End " ) ,
SelectionModel ( options : [ " Leverage agile " , " frameworks " , " robust synopsis " , " high level " , " overviews " ,
" Iterative approaches " , " corporate strategy " , " foster collaborative " ,
" overall value " , " proposition " , " Organically grow " , " holistic world view " ,
" disruptive " , " innovation " , " workplace diversity " , " empowerment " ] ) ,
2023-12-19 15:17:30 +00:00
" Maecenas faucibus mollis interdum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. " ,
2023-12-19 15:17:30 +00:00
GridItem ( color : UIColor ( red : 237 / 255.0 , green : 73 / 255.0 , blue : 86 / 255.0 , alpha : 1 ) , itemCount : 6 ) ,
2023-12-19 15:17:30 +00:00
User ( pk : 2 , name : " Ryan Olson " , handle : " ryanolsonk " ) ,
2023-12-19 15:17:30 +00:00
HorizontalCardsSection ( cardCount : 10 ) ,
2023-12-19 15:17:30 +00:00
SwipeActionSection ( ) ,
2023-12-19 15:17:30 +00:00
" Praesent commodo cursus magna, vel scelerisque nisl consectetur et. " ,
2023-12-19 15:17:30 +00:00
User ( pk : 4 , name : " Oliver Rickard " , handle : " ocrickard " ) ,
2023-12-19 15:17:30 +00:00
HorizontalCardsSection ( cardCount : 2 ) ,
2023-12-19 15:17:30 +00:00
GridItem ( color : UIColor ( red : 56 / 255.0 , green : 151 / 255.0 , blue : 240 / 255.0 , alpha : 1 ) , itemCount : 5 ) ,
2023-12-19 15:17:30 +00:00
" Nullam quis risus eget urna mollis ornare vel eu leo. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. " ,
2023-12-19 15:17:30 +00:00
User ( pk : 3 , name : " Jesse Squires " , handle : " jesse_squires " ) ,
2023-12-19 15:17:30 +00:00
GridItem ( color : UIColor ( red : 112 / 255.0 , green : 192 / 255.0 , blue : 80 / 255.0 , alpha : 1 ) , itemCount : 3 ) ,
2023-12-19 15:17:30 +00:00
" Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. " ,
2023-12-19 15:17:30 +00:00
GridItem ( color : UIColor ( red : 163 / 255.0 , green : 42 / 255.0 , blue : 186 / 255.0 , alpha : 1 ) , itemCount : 7 ) ,
2023-12-19 15:17:30 +00:00
User ( pk : 1 , name : " Ryan Nystrom " , handle : " _ryannystrom " )
2023-12-19 15:17:30 +00:00
]
override func viewDidLoad ( ) {
super . viewDidLoad ( )
// L a y o u t
let layout = UICollectionViewCompositionalLayout { [ weak self ] ( sectionIndex : Int , layoutEnvironment : NSCollectionLayoutEnvironment ) -> NSCollectionLayoutSection ? in
guard let self = self else {
return nil
}
let controller = self . adapter . sectionController ( forSection : sectionIndex )
guard let controller = controller as ? CompositionLayoutCapable else {
return nil
}
return controller . collectionViewSectionLayout ( layoutEnvironment : layoutEnvironment )
}
// C o l l e c t i o n V i e w
let collectionView = UICollectionView ( frame : . zero , collectionViewLayout : layout )
self . collectionView = collectionView
view . addSubview ( collectionView )
adapter . collectionView = collectionView
adapter . dataSource = self
}
override func viewDidLayoutSubviews ( ) {
super . viewDidLayoutSubviews ( )
collectionView ? . frame = view . bounds
}
// MARK: L i s t A d a p t e r D a t a S o u r c e
func objects ( for listAdapter : ListAdapter ) -> [ ListDiffable ] {
return data . map { $0 as ! ListDiffable }
}
func listAdapter ( _ listAdapter : ListAdapter , sectionControllerFor object : Any ) -> ListSectionController {
switch object {
case is String :
return ExpandableComposableSectionController ( )
2023-12-19 15:17:30 +00:00
case is GridItem :
return GridComposableSectionController ( )
2023-12-19 15:17:30 +00:00
case is User :
return UserComposableSectionController ( )
2023-12-19 15:17:30 +00:00
case is HorizontalCardsSection :
return HorizontalComposableSectionController ( )
2023-12-19 15:17:30 +00:00
case is SwipeActionSection :
return SwipeActionComposabelSectionController ( )
2025-03-19 17:14:23 +00:00
case is ActivityItem :
return ActivityComposableSectionController ( )
case is SelectionModel :
return SelectionComposableSectionController ( )
2023-12-19 15:17:30 +00:00
default :
return ListSectionController ( )
}
}
func emptyView ( for listAdapter : ListAdapter ) -> UIView ? { return nil }
}