TestsTested | ✓ |
LangLanguage | Obj-CObjective C |
License | MIT |
ReleasedLast Release | Oct 2016 |
Maintained by Nikita Ermolenko.
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
Framer is actively maintained.
[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.4
v1.3
v1.1
v1.0
Nikita Ermolenko, [email protected]
Framer is available under the MIT license. See the LICENSE file for more info.