TestsTested | ✓ |
LangLanguage | Obj-CObjective C |
License | MIT |
ReleasedLast Release | Mar 2016 |
Maintained by Mike Amaral.
Façade is a UIView
category allowing you to build your UI in real-world terms, in the same way you would explain the layout to someone in conversation. It is a conglomeration of convenience methods wrapping lots of annoying and tedius frame algebra into a human-readable format. Because of this, it's lightweight and flexible enough to allow you to build great looking UI's quickly and easily define unique layout experiences based on device orientation or type.
[_headerImageView anchorTopCenterFillingWidthWithLeftAndRightPadding:0 topPadding:0 height:250];
NSArray *shareButtons = @[_facebookButton, _twitterButton, _googleButton, _pinterestButton];
[_headerImageView groupVertically:shareButtons centerRightWithRightPadding:7 spacing:7 width:45 height:45];
[_avatarImageView alignUnder:_headerImageView matchingCenterWithTopPadding:-50 width:100 height:100];
[_nameLabel alignUnder:_avatarImageView centeredFillingWidthWithLeftAndRightPadding:7 topPadding:14 height:28];
[_usernameLabel alignUnder:_nameLabel centeredFillingWidthWithLeftAndRightPadding:7 topPadding:2 height:19];
[_bioLabel sizeToFit];
[_bioLabel alignUnder:_usernameLabel centeredFillingWidthWithLeftAndRightPadding:15 topPadding:10 height:CGRectGetHeight(_bioLabel.frame)];
[_followButton alignUnder:_bioLabel matchingCenterWithTopPadding:20 width:250 height:44];
[_scrollView groupHorizontally:@[_messageButton, _statsButton, _addButton] centeredUnderView:_followButton topPadding:30 spacing:40 width:60 height:60];
[_messageLabel alignUnder:_messageButton matchingCenterWithTopPadding:7 width:80 height:13];
[_statsLabel alignUnder:_statsButton matchingCenterWithTopPadding:7 width:80 height:13];
[_addLabel alignUnder:_addButton matchingCenterWithTopPadding:7 width:80 height:13];
pod 'Facade'
to your Podfile, and run pod install
UIView+Facade.h
in your view controller.layoutSubviews
method, call the applicable UIView+Facade
convenience methods to define how you want your UI to be laid out.Many UI layouts "start" with a view anchored to the top/corner of the screen, such as a profile view with an avatar in the top-left corner. Doing something like this is easy with Façade - simply tell the view where to anchor itself, and provide the applicable padding/size parameters, and it will do the rest for you. Doing this in viewWillLayoutSubviews
also allows Façade to keep this layout consistent in both orientations, as shown below:
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self layoutFacade];
}
- (void)layoutFacade {
CGFloat padding = 10;
CGFloat size = 50;
[_redView anchorTopLeftWithLeftPadding:padding topPadding:padding width:size height:size];
[_orangeView anchorTopCenterWithTopPadding:padding width:size height:size];
[_yellowView anchorTopRightWithRightPadding:padding topPadding:padding width:size height:size];
[_greenView anchorCenterRightWithRightPadding:padding width:size height:size];
[_blueView anchorBottomRightWithRightPadding:padding bottomPadding:padding width:size height:size];
[_purpleView anchorBottomCenterWithBottomPadding:padding width:size height:size];
[_cyanView anchorBottomLeftWithLeftPadding:padding bottomPadding:padding width:size height:size];
[_brownView anchorCenterLeftWithLeftPadding:padding width:size height:size];
[_grayView anchorInCenterWithWidth:size height:size];
}
While most layouts start with one or more anchor views, the rest of the components are typically laid out relative to other sibling views and often their sizes are dependant both on these sibling views and their superview. We've compiled the most common relative layout types to make this process as easy as possible. Here are a few examples, showing the results in both orientations:
[_redView anchorTopLeftWithLeftPadding:10 topPadding:10 width:100 height:100];
[_orangeView alignToTheRightOf:_redView matchingTopAndFillingWidthWithLeftAndRightPadding:10 height:20];
[_greenView alignUnder:_orangeView matchingLeftAndFillingWidthWithRightPadding:10 topPadding:5 height:20];
[_blueView alignUnder:_greenView matchingLeftAndFillingWidthWithRightPadding:10 topPadding:5 height:50];
[_brownView alignUnder:_redView matchingLeftAndFillingWidthWithRightPadding:10 topPadding:10 height:30];
[_purpleView alignUnder:_brownView matchingRightWithTopPadding:10 width:100 height:40];
[_yellowView alignUnder:_purpleView centeredFillingWidthAndHeightWithLeftAndRightPadding:10 topAndBottomPadding:10];
You can also position views between two views vertically or horizontally:
[_purpleView alignBetweenLeft:_orangeView andRight:_yellowView matchingTopWithLeftAndRightPadding:10 height:50];
[_brownView alignBetweenTop:_orangeView andBottom:_greenView matchingLeftWithTopAndBottomPadding:10 width:50];
[_grayView alignBetweenLeft:_greenView andRight:_blueView matchingTopWithLeftAndRightPadding:10 height:50];
[_cyanView alignBetweenTop:_yellowView andBottom:_blueView matchingLeftWithTopAndBottomPadding:10 width:50];
Sometimes you want a number of view components to be grouped together and have this group as a whole be laid out relative to another view. A common example of this would be share buttons - perhaps on top of an image there's share icons for facebook, pinterest, twitter, etc. This can easily be achieved by telling the appropriate superview to group an array of child views with a particular layout, padding, and sizes. Here's two-examples-in-one:
[_redView groupVertically:@[_orangeView, _yellowView, _greenView] inUpperRightWithRightPadding:10 topPadding:10 spacing:10 width:50 height:50];
[self.view groupHorizontally:@[_blueView, _purpleView, _brownView] centeredUnderView:_redView topPadding:10 spacing:10 width:50 height:50];
The cool part of this is that it allows you to add, remove, or reorganize views to a group without having to recalculate all of the frames for each.
[_redView groupVertically:@[_orangeView, _yellowView] inUpperRightWithRightPadding:10 top:10 spacing:10 width:50 height:50];
[self.view groupHorizontally:@[_greenView, _blueView, _purpleView, _brownView, _blackView] centeredUnderView:_redView topPadding:10 spacing:10 width:50 height:50];
If you want to contribute, open a pull request. Please do your best to keep the style/formatting consistent with the current project and MAKE SURE TO ADD TESTS!
If you have questions, feature requests, etc., I would prefer if you created an issue rather than email me directly.
This project is made available under the MIT license. See LICENSE.txt
for details.