Framer is a great layout framework which wraps manually calculation frames with a nice-chaining syntax.
It's also available for Swift but with another name - Framezilla
CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over eighteen thousand libraries and can help you scale your projects elegantly. You can install it with the following command:
$ sudo gem install cocoapodsTo install Framer, simply add the following line to your Podfile:
pod "Framer"then add
#import <Framer/Framer.h>    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.top(10).and.bottom(10);
        framer.right(10).and.left(10);
    }];... or just
    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.edges(UIEdgeInsetsMake(10, 10, 10, 10));
    }];For example, you just want to centered subview relative superview with constant width and height.
So easy to do it with Framer :
    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.width(100).and.height(100);
        framer.super_centerX(0);
        framer.super_centerY(0);
    }];    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.width(100).and.height(100);
        framer.super_centerX(0);
        framer.super_centerY(0);
    }];
    
    [self.view2 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.width(50).and.height(50);
        framer.bottom_to(self.view1.nui_top, 0);
        framer.left_to(self.view1.nui_right, 0);
    }];... or maybe so?
    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.width(100);
        framer.height(100);
        framer.super_centerX(0).and.super_centerY(0);
    }];
    
    [self.view2 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.top(10);
        framer.bottom(10);
        framer.left(10);
        framer.width_to(self.view2.nui_height, 0.5); // height*0.5
    }];That's important to point out relations for two views.
    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.bottom_to(self.view1, 0);
    }];    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.bottom_to(self.view1.nui_top, 0);
    }];At first you should configurate all subviews and then configure container.
    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.width(200).and.height(200);
        framer.super_centerX(0);
        framer.super_centerY(0);
    }];
    
    [self.label1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.top(0).and.left(0);
        framer.sizeToFit();
    }];
    
    [self.label2 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.top_to(self.label1.nui_bottom, 0).and.left(0);
        framer.sizeToFit();
    }];
    
    [self.container installFrames:^(NUIFramer * _Nonnull framer) {
        framer.container();
        framer.super_centerX(0);
        framer.super_centerY(0);
    }];It's very convenient use many states for animations, because you can just configure all states in one place and when needed change frame for view - just apply needed state! Awesome, is'n it?
- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    
    /* Configure frame for '0' state */
    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.width(10);
        framer.height(10);
        framer.super_centerX(0).and.super_centerY(0);
    }];
    
    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.width(40);
        framer.height(40);
        framer.super_centerX(0).and.super_centerY(0);
    } forState:@1];
    
    [self.view1 installFrames:^(NUIFramer * _Nonnull framer) {
        framer.width(100);
        framer.height(100);
        framer.super_centerX(0).and.super_centerY(0);
    } forState:@2];
}set new state and animate it:
/* Next time when viewDidLayoutSubviews will be called, self.view1 configure frame for state 2. */
    self.view1.nui_state = @2;
    [self.view setNeedsLayout];
    [UIView animateWithDuration:1.0 animations:^{
        [self.view layoutIfNeeded];
    }];    CGFloat width = NUI_WIDTH(view);
    CGFloat midX = NUI_MID_X(view);v1.5
- Updated documentation.
 - Added 
widthToFitandheightToFit. 
v1.4
- Added macroses for getting width, height etc.
 
v1.3
- Added centerX and centerY methods for just setting center point.
 - Added width_to and height_to for configure height/width relatively specific view.
 
v1.1
- Added 'nui' prefix to relations(left, right etc).
 - Added possibility to configure frame for special state.
 
v1.0
- First release version. Configure frame blocks.
 
- Other platforms support
 - Swift support
 - More tests
 
Nikita Ermolenko, [email protected]
Framer is available under the MIT license. See the LICENSE file for more info.


