最近专门去研究了约束框架Masonry,对里面的链式调用方法感到很震惊,完全没有想到可以那样的运用block,同时感觉到使用链式方法在代码上感觉更加简洁。因此就一直想去写个类似的链式调用框架。
正好最近在界面绘制上(纯代码),感觉代码比较繁琐(经常要写一堆的代码),并且有大量重复性的工作,因此想写这一个小框架来改善这方面的情况。
成果对比:
之前创建view的方式:
UIView * testView = [[UIView alloc] initWithFrame:CGRectZero];
testView.backgroundColor = [UIColor redColor];
testView.layer.cornerRadius = 5;
testView.layer.masksToBounds = YES;
testView.userInteractionEnabled = NO;
使用框架后的创建方式:
UIView * testView = UIView.msf_viewModel.frame(CGRectZero).backGroundColor([UIColor redColor]).cornerRadius(5)
.masksToBounds(YES).userInteractionEnabled(NO).bindView;
或者(类似Masonry的创建方式)
UIView * testView = [UIView msf_makeViewWithViewModel:^(MSFUIViewModel * _Nonnull viewModel) {
viewModel.frame(CGRectZero).backGroundColor([UIColor redColor]).cornerRadius(5);
viewModel.masksToBounds(YES).userInteractionEnabled(NO);
}];
创建UILabel
,UIButton
,UIImageView
的时候,只需要将上面的调用类名替换即可。(基本上这四个类的可设置属性,框架都支持链式设置)
可能你发现代码量其实没有减少多少
这都被你发现了……(手动狗头+手动滑稽+😂)
当然我写的这个框架并不是真的一点用处都没有,还提供了以下的拷贝方法
因为在开发过程中,经常发现有很多label长的一样,或者只有极个别的不一样,虽然可以command+c
和command+v
,但是整体下来,感觉代码还是很长的。
使用下面的方法,可以深拷贝一份view或者其子类
UIView * copyView = UIView.msf_copyView(view); // 拷贝view,生成了copyView
UILabel * copyLabel = UIView.msf_copyView(label); // 拷贝label,生成了copyLabel
UIButton * copyButton = UIView.msf_copyView(button); // ……
UIImageView * copyImageView = UIView.msf_copyView(imageView); // ……
拷贝过后,如果想自己再修改一部分东西,可以这样
// 拷贝label,生成了copyLabel,然后修改了copyLabel的text和y坐标
UILabel * copyLabel = [UIView msf_copyViewUpdateInfoWithModel:^(MSFUIViewModel * _Nonnull viewModel) {
viewModel.originY(400).text(@"我修改了标题");
}](label);
// 拷贝button,修改title和title的字体大小
UIButton * copyButton = [UIView msf_makeViewWithViewModel:^(MSFUIViewModel * _Nonnull viewModel) {
viewModel.title(@"haha",UIControlStateNormal).titleFontSize(12);
}](button);
原理
其实也没什么原理,主要还是学的Masonry对block的运用:创建MSFUIViewModel类的对象A,利用A的get方法拿到一个有返回值的block,然后直接调用block,拿到block返回的A,继续调用get方法,直到设置完自己要设置的属性即可。
写这个东西的时候,主要的阻力还是方法的返回值类型。因为返回的对象是UIView
,UILabel
,UIButton
,UIImageView
,后面三个是第一个的子类,然后后面三个又是平行的关系,各个属性值又不一样。
解决的方式是:根据调用方法的类名或者传过来拷贝的对象获取到要生成的对象的类型,再去调用相关的设置方法。方法返回的时候,是使用了__kindOf
这个关键词(返回当前类或者其子类),这样就使用过程中就不会产生类型不匹配的警告
想看一下源码的可以点这里,GitHub地址:https://github.com/mushao1990/MSFUIConvenice
网友评论