已经有两个星期没有更新博客了实属无奈,最近实在是太忙了昨天刚刚Release,习惯是一定要遵守的,即使没有时间也要挤出来。好了言归正传,这次要分享的内容主要是我之前在项目上遇到一个布局方面的问题。
首先我们来看一张设计图:
上面分别是iPhone5s,iPhone6,iPhone6s以及iPad的四张设计图,对应了我们的日历模块,我分别对图上的几个特别的点进行了标注,我们可以发现基本上所有的标注尺寸都是不同的,原因是因为考虑到不同设备大小尺寸的不同,所以在美观度上设计师分别设计了四种方案。
那么我所遇到的问题就是如何采用一种方案,把关于设备适配这种逻辑从代码里解偶出来,这是我想要做的。
我们的项目是通过纯代码的AutoLayout(Masonry实现)来布局的,那么之前的代码中就存在类似于以下结构的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[self.measureTopView mas_makeConstraints:^(MASConstraintMaker *make) { CGFloat measureTopViewHeight; CGFloat measureTopViewLeftAndRightToSuperViewDistance; if (WIDTH_SCREEN == kBMTDeviceScreenWidthIphone5) { measureTopViewHeight = 105.0f; measureTopViewLeftAndRightToSuperViewDistance = 12.0f; } if (WIDTH_SCREEN == kBMTDeviceScreenWidthIphone6) { measureTopViewHeight = 105.0f; measureTopViewLeftAndRightToSuperViewDistance = 15.0f; } else { measureTopViewHeight = 114.0f; measureTopViewLeftAndRightToSuperViewDistance = 20.0f; } make.top.equalTo(self); make.left.equalTo(self.mas_left).offset(measureTopViewLeftAndRightToSuperViewDistance); make.right.equalTo(self.mas_right).offset(-measureTopViewLeftAndRightToSuperViewDistance); make.height.mas_equalTo(measureTopViewHeight); }]; |
基本上大部分的View里都会充斥着这类代码非常不美观又提高了耦合度。所以我们的目标就是将这类代码从里面分离出来View只做数据的展示而不做其它的判断。
一般在iOS中界面适配常用到的方式就是storyboard的AutoLayout的布局,但是我个人不喜欢这种布局方式,原因有三点:
- 在于xib在多人合作开发时如果有冲突是不能merge的,
- 对于那种会动态修改的界面来说,我们还需要在代码中修改界面的属性,那不如直接就采用纯代码的布局方便。
- 采用纯代码的布局有利于我们更好的了解控件的属性。但即使我们使用了storyboard+Sizeclass的方式也解决不了我们的问题,因为Sizeclass其实就是解决横屏适配和iPhone iPad共享一个设计板的需要。
第二种我想到可以解决问题的方案是我们对Masonry进行一次关于Device的扩展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
@interface MASConstraint (DeviceAdapter) #define mas_equalTo_iPhone5Or5S(...) equalTo_iPhone5Or5S(MASBoxValue((__VA_ARGS__))) #define mas_equalTo_iPhone6Or6S(...) equalTo_iPhone6Or6S(MASBoxValue((__VA_ARGS__))) #define mas_equalTo_iPhone6POr6SP(...) equalTo_iPhone6POr6SP(MASBoxValue((__VA_ARGS__))) #define mas_equalTo_iPhoneIPad(...) equalTo_iPhoneIPad(MASBoxValue((__VA_ARGS__))) #define mas_equalTo_iPhone5Or5SOr6Or6S(...) equalTo_iPhone5Or5SOr6Or6S(MASBoxValue((__VA_ARGS__))) #define mas_equalTo_iPhone6POr6SPOrIPad(...) equalTo_iPhone6POr6SPOrIPad(MASBoxValue((__VA_ARGS__))) - (MASConstraint * (^)(id attr))equalTo_iPhone5Or5S; - (MASConstraint * (^)(id attr))equalTo_iPhone6Or6S; - (MASConstraint * (^)(id attr))equalTo_iPhone6POr6SP; - (MASConstraint * (^)(id attr))equalTo_iPhoneIPad; - (MASConstraint * (^)(id attr))equalTo_iPhone5Or5SOr6Or6S; - (MASConstraint * (^)(id attr))equalTo_iPhone6POr6SPOrIPad; - (MASConstraint * (^)(CGFloat offset))iPhone5Or5SOffset; - (MASConstraint * (^)(CGFloat offset))iPhone6Or6SOffset; - (MASConstraint * (^)(CGFloat offset))iPhone6POr6SPOffset; - (MASConstraint * (^)(CGFloat offset))iPhoneIPadOffset; - (MASConstraint * (^)(CGFloat offset))iPhone5Or5SOr6Or6SOffset; - (MASConstraint * (^)(CGFloat offset))iPhone6POr6SPOrIPadOffset; @end |
好有了这一层的扩展我们就可以把之前代码修改成如下的样子:
1 2 3 4 5 6 |
归正传,这次要分享的内容主要是我之前在项目上遇到一个布局方面的问题。
首先我们来看一张设计图:
那么我所遇到的问题就是如何采用一种方案,把关于设备适配这种逻辑从代码里解偶出来,这是我想要做的。 我们的项目是通过纯代码的AutoLayout(Masonry实现)来布局的,那么之前的代码中就存在类似于以下结构的代码:
基本上大部分的View里都会充斥着这类代码非常不美观又提高了耦合度。所以我们的目标就是将这类代码从里面分离出来View只做数据的展示而不做其它的判断。
第二种我想到可以解决问题的方案是我们对Masonry进行一次关于Device的扩展:
|