MyLayout是一个可以非常简单和方便的实现各种界面布局的第三方开源库。在我的github项目中大部分DEMO都是通过代码来实现界面布局的,但这并不是表示MyLayout不支持XIB和SB。
在构建一个应用的MVC框架中,我们希望模型、视图、控制这三部分都尽可能的低耦合,而苹果推荐的视图部分构建则是通过XIB或者SB来完成的。因为MyLayout中的各种布局视图类其实都是从UIView派生的,因此MyLayout是完全可以和XIB以及SB混合使用的。
MyLayout的一些布局视图属性以及子视图的扩展布局属性是可以在XIB或者SB界面编辑器里面进行设置的。唯一的一个缺点是这些属性的设置不能起到所见即所得的效果。 因为MyLayout是一个独立而完整的界面布局框架,因此您可以和系统默认的AutoLayout混合使用,也可以完全独立的单独使用。
不和AutoLayout以及Size Classes结合使用的方法
当您使用MyLayout进行界面布局时,那么要求至少应该存在一个布局视图,否则所有关于子视图的扩展布局属性都无效,因为子视图的这些扩展属性只有在布局视图里面才有用。MyLayout是一个完整而独立的布局体系,因此要求我们的布局视图内的子视图不能再通过设置AutoLayout的约束来进行布局了,因此我们可以在XIB或者SB中完全不需要AutoLayout以及Size Classess的特性。
第一步就是要将XIB或者SB中对AutoLayout和Size Classes的支持去掉:
取消对AutoLayout的支持
第二步就是将视图控制器中的根视图的类名转化为对应的布局视图类:
根视图的类名转换
第三步将类名转换后您可以切换到Show the attributes inspector 标签中进行布局视图特有属性的设置:
布局视图的属性设置.png
您会发现上面图中出现了大量对MyLayout布局特有属性以及子视图的扩展布局属性设置的地方。你可以在这里设置布局视图以及子视图的扩展属性。我这里就分别设置了根视图布局的topPadding属性值为20,subviewVSpace属性值为30。
在XCODE中如果您想要将视图类的自定义属性出现在attributes inspector 中的话,您需要在您的自定义属性前面加上IBInspectable 关键字。比如下面的定义:
@property(nonatomic, assign) IBInspectable CGFloat myTop;@property(nonatomic, assign) IBInspectable CGFloat myLeading;@property(nonatomic, assign) IBInspectable CGFloat myBottom;@property(nonatomic, assign) IBInspectable CGFloat myTrailing;
目前支持** IBInspectable关键字的属性只有NSString、BOOL、int、float、double、CGSize、UIColor、UIImage等基本属性,而对枚举类型以及其他对象类型暂时不支持,那么假如我想设置枚举类型的值比如布局视图的gravity属性时怎么办呢?我们可以切换到Show the Identify inspector标签中的 User Defined Runtime Attributes列表中
设置自定义扩展属性
您会发现所有设置的扩展属性都会在这里同时出现,因此您也可以在这里设置自定义的扩展属性。 当某个自定义属性无法在attributes inspector标签中设置时,您可以在User Defined Runtime Attributes 进行设置,我在这里添加了对布局视图gravity的设置。这里设置为1799的原因是MyGravity_Fill
的枚举值就是1799(参考MyGravity类型枚举值的定义)。通过gravity属性设置了所有子视图均分高度和以及宽度和布局视图相等。设置完毕后我们分别按顺序添加3个高度一致的子视图如下:
依次添加子视图
上面的中我们可以看出,我们并不需要为子视图设置任何附加的约束,我们也没有为子视图设置扩展属性。我们只是按顺序添加上去。下面的图片就是实际的运行的结果:
布局运行结果
从上面的例子里面我们可以看出MyLayout是可以完全和XIB以及SB无缝结合的,我们在没有任何编码的情况下,通过几个简单属性的设置就实现了三个子视图的垂直高度均分以及宽度和布局视图相等以及每个子视图之间间隔30的功能。(假如你用AutoLayout来设置约束的话,我相信要实现同样的功能,您一定要设置非常多的约束来完成吧。)在这里唯一的缺陷就是MyLayout的属性设置无法在XCODE界面编辑器中所见即所得。
上面的例子我们进行了简单的布局扩展属性设置,那么如果我们要实现布局套布局怎么办呢? 既然我们可以把根视图转化为一个布局视图类,那么我相信您可以举一反三了。我们只要直接在根布局视图中,先添加一个UIView视图,然后把类名改为对应想要使用的布局视图就可以了。我们将上面例子中的中间UILabel改为一个水平线性布局(需要注意的是在放置时需要将三个子视图的frame的高度设置为一致,这个gravity属性拉伸才能得到相同的高度。)。而水平线性布局则有2个子视图:
布局套布局
上图中我将中间的视图的UIView类改为了MyLinearLayout。并设置了orientation属性为1也就是水平线性布局方向,同时设置了水平线性布局的四周的边界为10。下面就是运行的实际效果:
布局套布局的运行效果
这样是不是非常的简单。当然如果您不想在XCODE的界面编辑器中设置布局视图的各种属性,而是想通过界面编辑器来建立视图,然后通过代码设置属性或者要设置界面编辑器无法设置的布局属性时。那么你需要将布局视图设置为一个IBoutlet插座变量,然后在对应的地方设置布局属性或者子视图扩展属性或者复杂的布局属性就可以了:
代码和编辑器结合布局
和AutoLayout结合使用方法
上面的例子介绍的是在不使用AutoLayout时如何将MyLayout和XIB以及SB结合的场景,那么如果我们使用AutoLayout并且想用到MyLayout的布局视图类怎么办呢?答案很简单:
MyLayout布局视图本身就和其他普通视图一样通过AutoLayout来设置约束,而布局视图里面的子视图则不能使用AutoLayout来设置约束,而是用上面介绍的方式来设置各种布局属性。
AutoLayout和MyLayout混合使用
TangramKit对XIB以及SB的支持
目前TangramKit并没有在XCODE的界面编辑器中定义出可设置的扩展属性。因此当你用TangramKit进行界面布局时,您可以在XCODE的界面编辑器中将对应的界面视图添加上去。然后通过建立插座变量来在代码中设置各种布局属性。
小结
从上面可以看出MyLayout并不排斥XIB或者SB,也并不排斥AutoLayout,相反如果您能够灵活的运用那么将会大大的减少您构建应用的时间和精力。
作者:欧阳大哥2013