【上集剧情概要:上集我们主要试着用连式结构写了一个简单地布局的设计的demo,首先通过block方式实现链式调用,然后封装添加布局的约束到block里面,实现了上下左右的简单布局】
好吧,各位观众,接下来抛砖引玉,逐渐去添加一些布局功能的时候到了。。。。。
首先,我们考虑一个问题,因为上集我们主要是默认相对视图为superview,而且都是用默认偏移量constant,并没有倍数关系,那么我们如何加入toItem和multiplier这两个参数呢???
用什么方式展示给用户更为好的呢???
思考中ing..........
好吧,最直接的办法就是添加两个参数,这样就凑齐了。。。。。
ok,我把代码封装了一下,变成下面的样子。。。
#import "UIView+GCFAdditions.h" @implementation UIView (GCFAdditions) - (UIView *(^)(UIView *toItem,float multiplier,NSInteger space))left { return [self addGCFConstraint:NSLayoutAttributeLeft]; } - (UIView *(^)(UIView *toItem,float multiplier,NSInteger space))right { return [self addGCFConstraint:NSLayoutAttributeRight]; } - (UIView *(^)(UIView *toItem,float multiplier,NSInteger space))top { return [self addGCFConstraint:NSLayoutAttributeTop]; } - (UIView *(^)(UIView *toItem,float multiplier,NSInteger space))bottom { return [self addGCFConstraint:NSLayoutAttributeBottom]; } - (UIView *(^)(NSInteger value))width { return ^(NSInteger value) { if (value) { NSLog(@"%ld",(long)value); } else { NSLog(@"%ld",(long)value); } self.translatesAutoresizingMaskIntoConstraints=NO; NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:value]; [self addConstraint:constraint]; return self; }; } - (UIView *(^)(NSInteger value))height { return ^(NSInteger value) { if (value) { NSLog(@"%ld",(long)value); } else { NSLog(@"%ld",(long)value); } self.translatesAutoresizingMaskIntoConstraints=NO; NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:value]; [self addConstraint:constraint]; return self; }; } -(UIView *(^)(UIView *toItem,float multiplier,NSInteger space))addGCFConstraint:(NSLayoutAttribute )att { return ^(UIView *toItem,float multiplier,NSInteger space) { if (space) { NSLog(@"%ld",(long)space); } else { NSLog(@"%ld",(long)space); } self.translatesAutoresizingMaskIntoConstraints=NO; NSLayoutConstraint *constaintTop = [NSLayoutConstraint constraintWithItem:self attribute:att relatedBy:NSLayoutRelationEqual toItem:toItem attribute:att multiplier:1.0 constant:space]; [self.superview addConstraint:constaintTop]; return self; }; } @end
添加了width和height两个属性
在调用里面使用变成:
self.view1.left(self.view,1,50) .right(self.view,1,-50) .top(self.view,1,100) .height(130); self.view2.left(self.view,1,50) .right(self.view,1,-50) .top(self.view1,1,100) .height(130); self.view3.left(self.view,1,50) .right(self.view,1,-50) .top(self.view2,1,100) .height(130);
好了,到这里,基本上可以调用简单地封装了,那么问题来了,其实我们还差一个参数,就是当前view相对于toItem的属性参数是一样的,我们同样要传参数过去吗???
所以这里考虑到参数过多,如是想要封装起来
好吧,各位童鞋我们现在来解决下面一个问题,就是如果
top(self.view1,1,100)
第一个参数有两种情况:
如果是UIView的话,默认与当前的属性相同.....
如果是UIView的属性的话,则使用当前的属性
-(UIView *(^)(id toItem,float multiplier,NSInteger space))addGCFConstraint:(NSLayoutAttribute )att { return ^(id toItem,float multiplier,NSInteger space) { if (space) { NSLog(@"%ld",(long)space); } else { NSLog(@"%ld",(long)space); } self.translatesAutoresizingMaskIntoConstraints=NO; if([toItem isKindOfClass:[GCFAttribute class]]) { GCFAttribute *attribute=(GCFAttribute *)toItem; NSLayoutConstraint *constaint=[NSLayoutConstraint constraintWithItem:self attribute:att relatedBy:NSLayoutRelationEqual toItem:attribute.view attribute:attribute.attribute multiplier:1.0 constant:space]; [self.superview addConstraint:constaint]; } else { NSLayoutConstraint *constaint=[NSLayoutConstraint constraintWithItem:self attribute:att relatedBy:NSLayoutRelationEqual toItem:toItem attribute:att multiplier:1.0 constant:space]; [self.superview addConstraint:constaint]; } return self; }; }
这里使用id类型传入参数:
如果是UIView的话,先转为UIView类型,attribute属性都设置为相同的即可。
如果是GCFAttribute的话,先转为GCFAttribute类型,attribute属性都设置为GCFAttribute的attribute即可。
好吧,那GCFAttribute主要做什么呢,主要是将View和attribute封装到一个类里面,这样便于参数的传输。
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface GCFAttribute : NSObject @property(nonatomic, strong) UIView *view; @property(nonatomic, assign) NSLayoutAttribute attribute; - (id)initWithView:(UIView *)view : (NSLayoutAttribute)layoutAttribute; @end
#import "GCFAttribute.h" @implementation GCFAttribute - (id)initWithView:(UIView *)view : (NSLayoutAttribute)layoutAttribute { self = [super init]; if (!self) return nil; _attribute =layoutAttribute; _view=view; return self; } @end
还有个问题需要解决,发现每次都要放三个参数,能不能再减少了呢???
其实multiplier这个参数很多时候默认为1,那么可以把它提出来吗,答案是肯定的,我们依旧使用Block链式调用的方式