LYPageLayout is a layout framework for iOS. It lets you easily build tables, grids, and more complex user interfaces.

LYPageLayout takes a declarative approach to building UI. It lets you focus on what your UI should look like, not the steps necessary to build it. It emphasizes a one-way data flow from immutable models to immutable sections that describe how views should be configured. It does the heavy lifting of building a view hierarchy from this description.

Getting Started

Clone the Github repository and run the example app.

$ git clone
$ open lypagelayout/Example.xcworkspace


The LYSection protocol is the primary building block for LYPageLayout. It acts as a “controller” for UICollectionViewCell, encapsulating behavior that would usually be spread across multiple datasource and delegate methods. Cell configuration, sizing, positioning, selection and more are handled within the section. Create custom implementations of LYSection in order to add new cell classes and cell types.

@protocol LYSection <NSObject>
@property (nonatomic, weak) id<LYSectionDelegate> delegate;
@property (nonatomic, readonly) Class cellClass;
- (void)configureCell:(UICollectionViewCell *)cell;
- (CGSize)sizeThatFits:(CGSize)size withCell:(UICollectionViewCell *)sizingCell;
- (BOOL)updateWithSection:(id<LYSection>)section;
@property (nonatomic, readonly) id<LYCollectionViewBehavior> behavior;
- (void)setup;
- (void)select;
- (NSArray *)operations;

The LYSectionDelegate protocol is the interface that LYPageViewController exposes to the section. From the delegate, the section can get its containing view controller, visible cell, and reload itself.

@protocol LYSectionDelegate <NSObject>
- (UIViewController *)parentViewControllerForSection:(id<LYSection>)section;
- (UICollectionViewCell *)visibleCellForSection:(id<LYSection>)section;
- (void)reloadSection:(id<LYSection>)section;


The LYPage collects an group of LYSection cells to be tiled on screen. UIViewController properties (title, rightBarButtonItems, …) can also be optionally set. And appearance methods (pageWillAppear, pageDidAppear, …) will be forwarded to the page.

@protocol LYPage <NSObject>
@property (nonatomic, readonly) NSArray *sections;
@property (nonatomic, weak) id<LYPageDelegate> delegate;
@property (nonatomic, readonly) NSString *title;
@property (nonatomic, readonly) UIView *titleView;
@property (nonatomic, readonly) NSArray *rightBarButtonItems;
@property (nonatomic, readonly) NSArray *leftBarButtonItems;
@property (nonatomic, readonly) UIRefreshControl *refreshControl;
@property (nonatomic, readonly) UIStatusBarStyle preferredStatusBarStyle;
@property (nonatomic, readonly) BOOL hidesBackButton;
@property (nonatomic, readonly) BOOL hidesNavigationBar;
@property (nonatomic, readonly) BOOL scrollEnabled;
- (void)pageWillAppear;
- (void)pageWillDisappear;
- (void)pageDidAppear;
- (void)pageDidDisappear;

The LYPageDelegate protocol is the interface that LYPageViewController exposes to the section. When properties on the page change, the UI can be updated by calling [id<LYPageDelegate> pageDidUpdate:].

@protocol LYPageDelegate <NSObject>
- (void)pageDidUpdate:(id<LYPage>)page;
- (UIViewController *)parentViewControllerForPage:(id<LYPage>)page;

View Controllers

So far we have methods of describing what we want on screen but how do we actually display it? LYPageViewController takes the page model and displays it inside a view controller. It has a very simple API.

@interface LYPageViewController : UIViewController
@property (nonatomic, strong) id<LYPage> page;


Documentation in progress…