iOS界面响应式布局方式对比

jopen 10年前

原文  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 工程例子, 跑起来再说.

</div>