iOS界面响应式布局方式对比
原文 http://www.ideawu.net/blog/archives/863.html
iPhone 手机的成功, iOS 操作系统功不可没. 而 iOS 操作系统的成功, 与早期 iPhone 单一的屏幕分辨率也有极大的关系. 不客气地说, 正因为早期 iPhone 手机只有一个分辨率, iOS 操作系统和其上面的 App 才不需要关心所谓的"响应式布局", "流式布局", "自动布局"这些技术, 它们只使用绝对定位的布局 - 每一个控件的大小和位置都是定死的, 几乎不变. 这样, iOS 应用开发者把精力放在了界面外观和交互体验, 最终促成了 iPhone/iOS 的成功.
不过, 从 iPad 的出现, 到 iPhone 5 发布, 以及后面的 iPhone 6/6+, iPhone/iOS 手机的屏幕分辨率开始多样化了, 这时, 界面布局便不能死守着绝对定位布局了.
为了解决这个问题, 苹果的方案是"Auto Resizing"和"Auto Layout", 特别是后者, 解决了界面动态布局的问题.
说实话, 所谓 Auto Layout 的原理非常简单, 也不是新事物. 其本质是相对布局, 而且很多年以前 .Net 的 UI 就有了 Dock/Anchor 特性. 原理简单, 符合人的一般思维, 这是个优点, 问题是, 苹果采用了一种非常丑陋的方式来实现这个原理. 不信, 你可以看看这段代码:
苹果的 Auto Layout
UIView *superview = self; UIView *view1 = [[UIView alloc] init]; view1.translatesAutoresizingMaskIntoConstraints = NO; [superview addSubview:view1]; UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10); [superview addConstraints:@[ //view1 constraints [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:padding.top], [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeLeft multiplier:1.0 constant:padding.left], [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-padding.bottom], [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeRight multiplier:1 constant:-padding.right], ]];
这段代码就是为了实现 padding(内边距), 但是用却用了一坨长长的代码. 任何人看到这段代码都应该感到恶心才对!
果不其然, iOS 程序员们发明了一些工具来消除这种难看的代码. 例如和 非死book 有关系的名为 Masonry 的框架, 封装了一些函数来. 例子如下:
封装的相对布局
UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10); [view1 mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(superview.mas_top).with.offset(padding.top); make.left.equalTo(superview.mas_left).with.offset(padding.left); make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom); make.right.equalTo(superview.mas_right).with.offset(-padding.right); }];
万变不离其宗, 其实质还是相对布局, 虽然代码量少了, 看起来简洁了, 而且好像在说"人话"(human nature language), 但是经验告诉我们, 用"人话"来做计算机编程, 基本上就是个笑话! 一是拖沓, 二是学习成本太高.
还有一点我必须要提到, 那就是相对布局的固有缺陷. 相对布局的缺陷就是其自身 - 相对. 相对意味着完成一件事, 你需要两个条件(两个参数). 如果你要动态地添加 UI 控件, 你不知道谁在你身边, 怎么办?
其实, 最好的布局方式, 应该是对于每一个控件, 它不需要关心其它的控件是谁, 每一个控件只需要自主地做好自己的份内事即可. 这就是 Web 界面布局(流式布局)的原理 - 每个人做好自己的事, 整体就自然而然好了.
那么, iOS 界面布局有没有这样简洁高效的方法的? 有! 使用 CocoaUI 界面库(libIKit.a), 你就可以使用 Web 界面布局的思路和原理来做 iOS 应用的界面布局. 这就是例子:
简洁的Web布局
[superview.style set:@"padding: 10;"];
没错! 只需要一行代码, 一行直观的符合程序员思维的代码, 每一个 Web 开发者都熟悉的的一行代码, 就完成所谓"自动布局" 40 行的代码. 不仅代码急剧减少, 思维还理顺了, 脑筋也不拧巴了.
CocoaUI(libIKit.a) 界面布局框架的功能不仅如此. 你知道, iOS 开发时我们经常用 .xib(nib) 来设计界面, 然后在代码里用一行代码来加载初始化界面. 使用, CocoaUI, 你也可以使用类似的技术, 直接从一个 HTML/XML 文件中加载初始化界面, 而且这个 HTML/XML 文件可以直接用浏览器来打开和预览!
如果你想提高 iOS 应用界面的开发效率, 可以试试 CocoaUI 吧. 先下载这个 Xcode 工程例子, 跑起来再说.