iOS 开发中的争议(二)UI到底应该用xib/storyboard完成,还是用手写代码来完成?

2023-10-27

文章来源:http://www.devtang.com/blog/2015/03/22/ios-dev-controversy-2/

参考文章:

关于代码手写UI,xib和StoryBoard

http://blog.csdn.net/likendsl/article/details/38731333 

《代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧》

http://www.onevcat.com/2013/12/code-vs-xib-vs-storyboard/

打算分享一些有争议的话题,并且表达一下我的看法。这是该系列的第二篇。

在本文中,我想讨论的是:对于 UI 界面的编写工作,到底应该用 xib/storyboard 完成,还是用手写代码来完成?

本着 “使用过才有发言权” 原则,我介绍一下我的经历:

  • 最早在网易开发 “ 有道云笔记 ” 的时候,我们是使用 xib 来制作界面的。
  • 三前年创业编写 “ 粉笔网 ” 的时候,我也是使用 xib 来制作界面的。
  • 之后开发 “ 猿题库 ” 的时候,我尝试了一下使用 storyboard 来制作界面,但最后放弃了。之后我把大部分界面编写工作都改成由手写代码来完成。
  • 在去年开发 “ 小猿搜题 ” 的时候,由于时间紧,我又再一次使用了 storyboard,但是我现在计划将其用手写代码来重构一次。

xib 使用调研情况

除了我本人的经历外,我也调研了一下我手机中装的所有的 App 的开发情况,我写了一个脚本,分析了我手机中一共 100 多个 App 包含的 xib 文件的个数。通常情况下一个 App 如果完全通过 xib/storyboard 来完成的话,那么编写包含的 xib 个数不应该少于 10 个(注:storyboard 在打包时会被拆解成多个它包含的 xib 文件)。

这个调研的最终结果,以及我分析用的脚本源码在 这里。我挑了一些比较有名的应用列在下面。(我另外也列出了它们包含的 js 的文件数量,这个可以反应出该应用对基于 UIWebView 的 Hybrid 编程的使用情况,不过与本次讨论主题无关。)

软件名字 nib 文件数 js 文件数
Mailbox 2.3.3.ipa 0 0
Twitter 6.0.1.ipa 0 0
objcio 1.0.3.ipa 0 0
播客 2.0.ipa 0 0
知乎日报 2.5.ipa 1 2
百度视频 6.2.2.ipa 1 3
高德导航 9.2.ipa 1 0
优酷 4.3.ipa 2 3
网易云音乐 2.3.1.ipa 2 0
滴滴打车 3.6.2.ipa 3 0
网易新闻 416.ipa 4 1
QQ 5.4.ipa 9 2
猿题库 4.1.0.ipa 9 0
京东 .ipa 10 0
搜狐视频 4.6.3.ipa 10 0
快的打车 3.7.ipa 11 0
小猿搜题 1.4.0.ipa 12 0
WeChat 6.1.1.ipa 13 20
Evernote 7.6.5.ipa 23 25
有道云笔记 4.3.1.ipa 40 11
来往 4.3.2.ipa 48 0
百度地图 7.6.1.ipa 76 227
易到用车 6.2.2.ipa 106 0
网易有道词典 5.2.2.ipa 114 9
美图秀秀 3.5.0.ipa 155 3
支付宝钱包 8.5.3.ipa 158 7
手机淘宝 5.2.4.ipa 188 0
易信 1.4.8.ipa 292 12
大众点评 7.0.2.ipa 1783 5
iMovie 211.ipa 4323 1

以上这个表格说明了即使是比较著名的 App,在使用 xib/storyboard 上,也有很大的差异。举几个例子:

  • QQ、WeChat(微信)和易信同属于社交类应用,而且按理说,由于用户量和开发时间更长,QQ 和微信应该比易信更加复杂,但是从 xib 数量上,前者 xib 的数量都非常少。这说明,在 QQ 和微信中,很多界面肯定是通过手写代码来完成的。

  • 滴滴打车、快的打车和易到用车同属于叫车软件,按理说滴滴打车、快的打车同时包含叫出租车和叫专车功能,应该比易到用车功能更多,更复杂。但是前者 xib 的数量都非常少。这也说明,滴滴打车、快的打车的界面很多是通过手写代码来完成的。

另外,像 Mailbox、播客 (Podcast)、Twitter、objcio 这些 App 中 xib 的数量为 0,说明其完全是用手写代码来完成 UI 界面编写的。

当然,也有一些能看出来几乎是由 xib 构成的应用,例如大众点评、美图秀秀、网易有道词典。而苹果的 iMovie 使用了 4000 多个 xib,真让人不敢相信。我后来仔细看了一下,原来是因为 iMovie 做了国际化,每种语言大概有 120 个 xib,因为支持了将近 40 个语言,所以 xib 数量变成了 4000 多个。大众点评的每个 xib 也被切分成了 4 个,具体用处我还没研究,如下是一个示例:

1
2
3
4
./Payload/DPScope.app/WEDHotelShopInfoMainModule.nib
./Payload/DPScope.app/WEDHotelShopInfoMainModule.nib/objects-8.0+.nib
./Payload/DPScope.app/WEDHotelShopInfoMainModule.nib/objects.nib
./Payload/DPScope.app/WEDHotelShopInfoMainModule.nib/runtime.nib

讨论

就上面的调研我们就可以看出,其实大家对于是否应该使用 xib 做界面是有争议的。在实际案例中:

  • 既有像 Twitter,Mailbox,objcio 这样完全不使用 xib 做界面的情况。
  • 也有像 QQ、微信、滴滴打车、网易新闻、猿题库这样少量使用 xib 的情况。
  • 也有像支付宝、大众点评这样重度使用 xib 的情况。

那么我就从我的角度把用与不用 xib 的优缺点表达一下。

使用 xib 和 storyboard 的优点

  • 开发界面所见即所得,可以快速通过拖拽构造界面。
  • 你可以从 storyboard 中很方便地梳理出所有View Controller的界面间的调用关系。这一点对于新加入项目组的开发同事来说,比较友好。
  • 使用 Storyboard 可以使用Table View Controller的 Static Cell 功能。对于开发一些 Cell 不多,但每个 Cell 都不一样的列表类设置界面会比较方便。
  • 通过实现 – (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 方法,每个 View Controller 的跳转逻辑都聚集在一处,这方便我们统一管理界面跳转和传递数据。
  • Storyboard 可以方便将一些常用功能模块化和复用。例如 WWDC2011 年介绍 Storyboard 的视频就将微博分享功能模块化成一个单独的 Storyboard。

使用 xib 和 storyboard 的缺点

  • xib 对版本管理是灾难。storyboard 实际上的多个 xib 的集合,所以更容易让多人编辑产生冲突。而虽然它们是 xml 格式,但是冲突解决起来还是不如代码那么容易。
  • 苹果对 xib, storyboard 的设计中带有当前电脑的操作系统版本和 Xcode 版本。所以如果两个协作的开发者电脑操作系统或 Xcode 有不一样的话,每次打开必定会修改这个文件。另外即使操作系统版本和 Xcode 版本一样,有些时候打开看也会造成一些自动的修改。
  • storyboard 带来的 segue 的概念对于开发来说并不省事,特别是在需要传递参数的时候。如果是用程序内部 trigger 一个 segue,那么需要在另一个回调的地方设置 dest view controller 的参数信息。
  • 我们发现 xib 中设置的颜色值并不精确,RGB 在真机 / 模拟器上常常会有 10 多像素的偏差。
  • xib 和 storyboard 对继承的支持并不友好。无法做界面的继承。
  • xib 和 storyboard 对搜索支持并不友好,无法方便地在 Xcode 中查找关键词(但是可以通过写 bash 命令来查找)。
  • storyboard 对组合支持得不太好,不允许在一个 xib 中附带多个子 view。
  • xib 和 storyboard 不太方便做界面的模块化管理,比如我们想统一修改界面中所有按钮的字体样式,那么在 xib 和 storyboard 只能一个一个手工修改,而如果是代码编写的,则只需要改一个工厂方法的实现即可。
  • 对于复杂的 App,storyboard 的性能会比较差。

关于手写 UI 界面的一些挑战

所以我更喜欢用代码编写 UI 界面,加上现在移动开发对于 App 要求的需求越来越强烈,很多复杂的交互效果需要在代码中编写,这种情况下 xib 能提供的帮助越来越有限。

但是 xib 提供的 “所见即所得” 这种优势还是巨大的,如果我们是手写界面,那么调试起来是非常痛苦的。在这一里,我给大家推荐购买 Reveal 这个界面调试工具,Reveal 可以在 App 运行时动态地修改界面元素的参数,这样我们就可以一次性在代码中把界面元素的字体、颜色、位置这些参数在 Reveal 调试好,避免多次重启运行来调试界面。我在我的 《iOS 开发进阶》 书里,也花了一整章来介绍 Reveal 的使用。如下是书中的一个 Reveal 运行时截图:

总结

其实,你完全不需要做一个 “艰难的决定”,你可以像 QQ 和微信那样,根据具体情况来选择性的使用 xib 和 storyboard。这里有我的一些建议:

  • 对于复杂的、动态生成的界面,建议使用手工编写界面。
  • 对于需要统一风格的按钮或UI控件,建议使用手工用代码来构造。方便之后的修改和复用。
  • 对于需要有继承或组合关系的 UIView 类或 UIViewController 类,建议用代码手工编写界面。
  • 对于那些简单的、静态的、非核心功能界面,可以考虑使用 xib 或 storyboard 来完成。

对于很多新手来说,他们接触到的都是使用 Interface Builder 来构造界面。希望本文让大家了解到 xib 和 storyboard 在开发中的争议,手写界面并不是一个小众的行为并且有很多好处,希望每一个人都能掌握它,并且在需要的时候根据具体情况来决定是否采用。

愿大家玩得开心~





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS 开发中的争议(二)UI到底应该用xib/storyboard完成,还是用手写代码来完成? 的相关文章

  • CLLocation Manager如何在一定距离后更新

    我正在使用 CLLocationManager didupdatelocations 如下所示 func locationManager manager CLLocationManager didUpdateLocations locati
  • 故事板 - 不支持的配置 8 个冲突的约束

    我正在使用故事板自动布局 我今天在编写警告消息时注意到 MainStoryboard iphone storyboard Unsupported Configuration 8 conflicting constraints 单击警告会进入
  • 在 Android 上使用 opus 剪辑从 IOS 发送的声音

    我正在 IOS 中从 audioUnit 录制音频 用 opus 编码字节并通过 UDP 将其发送到 android 端 问题是播放的声音有点削波 我还通过将原始数据从 IOS 发送到 Android 来测试声音 效果非常完美 我的 Aud
  • 如何建立辅助NSSortDescriptor排序键?

    我已成功按排序键对数据进行排序lastName 但我想知道如何排序lastName 然后由firstName 这是我用来排序的代码lastName NSSortDescriptor sortDescriptor NSSortDescript
  • UITableview 中的水平和垂直滚动[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 I want to make a lineup for a festival You can see what I want to a
  • 修补应用内购买黑客;卡在第四步

    正如我们许多人所知 苹果最近出现了一种情况 黑客可以免费获得任何应用内购买 苹果最近发布了这个文件 http developer apple com library ios releasenotes StoreKit IAP Receipt
  • 从 UIImagePickerController 相机视图推送 viewController

    我正在开发一款消息应用程序 类似于 WhatsApp 用户可以互相发送文本和图像消息 当用户想要发送图像时 他可以从相机胶卷中选择一张图像 也可以用相机拍摄一张图像 这就是我介绍的方式UIImagePickerController对于这两种
  • NSString – 静态还是内联?有性能提升吗?

    如果我写的话会有任何性能提升吗 NSString helloStringWithName NSString name static NSString formatString Hello return NSString stringWith
  • 在横向中自动调整 UITableCells 内容的大小

    在 UITableView 中 我通过 UILabels 将内容添加到单元格中 定义最佳尺寸 与单元格宽度允许的一样大 我注意到只有tableView contentSize width是可靠的 因为cell contentView bou
  • 如何在 iOS 9 上可靠地检测是否连接了外部键盘?

    在 iOS 9 之前 确定是否连接外部键盘的最可靠方法是监听UIKeyboardWillShowNotification并使文本字段成为第一响应者 如中所述这个问题 https stackoverflow com questions 289
  • 导入 RNCryptor 后架构 armv7 的未定义符号

    我导入了 RNCryptor 可以在这里找到 https github com rnapier RNCryptor https github com rnapier RNCryptor进入我的应用程序 但是 我在日志中收到了三个错误 Und
  • UIScrollView setZoomScale 将应用的旋转设置回零

    我已经从事地图替换工作很长一段时间了 整个事情的工作原理是UIScrollView由一个支持CATiledLayer 为了旋转我的地图 我旋转图层本身 使用CATransform3DMakeRotation 到目前为止效果很好 但如果我打电
  • 当地图视图只是屏幕的一部分时,如何在 iOS 模拟器中进行捏合?

    我在 iPad 上有一个视图 我正在添加MKMapView也就是说 全屏高度的一半 然而 当我尝试在 iOS 模拟器上进行捏合时 它不起作用 因为 to nubs 填充了模拟器上的整个 iPad 视图 And so with the map
  • 在 Xcode 5 中重命名 iOS 项目[重复]

    这个问题在这里已经有答案了 我需要重命名一个 iOS 项目 有没有办法在不开始一个全新项目的情况下做到这一点 我发现的所有其他信息都与 Xcode 4 或旧版本相关 这些方法似乎使项目崩溃 我在尝试任何名称更改之前创建了一个快照 在 Xco
  • UIButton的高亮状态由什么控制事件开始和结束

    我正在创建类似钢琴的视图UIButton作为钢琴键 什么UIControlEvents当按钮获得和失去突出显示状态时 我应该监听以获得回调吗 我试图创建子类UIButton并添加属性观察者highlighted并且运行良好 然而 有时我需要
  • 覆盖层不与 UITableView 一起滚动 - iOS

    我有一个 UITableView 类 它使用以下方法在转到下一个屏幕时调用加载覆盖 问题是这个加载屏幕不随列表滚动 所以如果你滚动一点并单击某些东西 加载屏幕不会显示 因为它位于顶部 如何让加载屏幕始终保持在 UITableView 的顶部
  • 如何使用 Swift 使用 TouchID?

    Apple 为 iOS 8 的 TouchID 实现提供的文档采用 Objective C 语言 有 Swift 版本吗 Objective C IBAction touchIDAvailable UIButton touchIDAvail
  • 将 Firebase 云消息传递与 Windows 应用程序结合使用

    我在 Android 和 iOS 应用程序中使用 Firebase Cloud Messaging 但是我还有此应用程序的 Windows Mac OS 版本 我想保留相同的逻辑 我知道 Firebase Cloud Messaging 可
  • 如何让按钮闪烁?

    我试图在扫描正确时将按钮的颜色 只是闪烁 闪烁 更改为绿色 在出现问题时将按钮的颜色更改为红色 我可以用这样的视图来做到这一点 func flashBG UIView animateWithDuration 0 7 animations s
  • PFQueryTableViewController 错误

    我正在遵循在线教程 使用 Parse 作为后端创建照片共享应用程序 我已经运行了两次教程 两次都从头开始创建应用程序 但在同一位置仍然出现相同的错误 我到处寻找解决方案 但仍然没有运气 我正在使用 PFQueryTableViewContr

随机推荐

  • python调用m文件

    系统环境 windows 64bit matlab 2018b 64bit python3 6 前提 windows下需要有matlab软件和python python调用m文件需要安装matlab engine 注意matlab版本与py
  • 类模板下运算符重载的两种用法

    1 template
  • java编写定时器,定时执行某个方法

    第一步 编写测试类 该类extends TimerTask 重新run 方法 run方法里面就是你要执行的逻辑代码 示例如下 import java text SimpleDateFormat import java util Date i
  • Python如何调用js函数?

    Python如何调用SDK的js函数 一 概述 二 环境准备 三 调用方法 步骤 四 Demo演示基础版 五 常见问题 六 深入了解 待更新 七 参考资料 一 概述 测试web前端 前端SDK web渗透流程等时 难免会需要调用前端js里面
  • 【Linux】浏览器写代码!部署code-server远程vscode网页

    部署code server远程vscode网页 在浏览器上写代码 参考文档 https developer aliyun com article 876967 slide 7 本文首发于 慕雪的寒舍 1 什么是code server 注意
  • 奔跑吧恐龙----基于JavaSwing的一个跑酷游戏

    1 游戏功能 随机出现障碍物 人物可以通过向上跳进行避免 游戏结束后出现分数 对难度进行一定的控制 当分数 gt 1000时难度升级 当分数 gt 4000时 难度再进行升级 并存在音乐播放功能 2 具体实现 2 1 model 1 Din
  • C++基于TCP/IP简单的客户端、服务器通信程序实例

    本篇文章实现了一个基于TCP 的一个非常简单的客户 服务器通信程序实例 该程序中通讯协议使用的是面向连接的TCP协议SOCK STREAM 服务器的ip地址为本地地址即 127 0 0 1 端口号为自定义的5099 大于1024即可 服务端
  • springBoot入门(快速搭建一个springBoot项目)

    目录 一 SpringBoot介绍 1 定义 2 springBoot简化的配置 3 应用打包 二 springBoot项目搭建 1 新建一个spring initializr项目 2 点击下一步 3 之后一个springBoot项目就构建
  • 好用的插件分享

    检查无用代码 Android studio gt 设置 gt Plugins gt 搜索PMD 安装QAPlug PMD 安装完成后重启Android studio
  • STM32--舵机(SG90)

    文章目录 一 介绍 二 工作原理 三 舵机的控制 四 设计流程 五 代码实现 六 舵机工程代码 七 备注 舵机 一 介绍 舵机是一种位置 角度 伺服的驱动器 适用于那些需要角度不断变化并可以保持的控制系统 目前在高档遥控玩具 如航模 包括飞
  • GitHub下载速度慢?找“马云”啊,干货帖

    大名鼎鼎的GitHub大家想必都知道 毕竟我这个无所事事的小白都知道 用多了GitHub的人应该对下面这种情况非常熟悉 当然 有的时候是不会下载失败的 还是会有个10k 8k的 注意我这里说的可不是工资 但是对于一个突然醒悟要好好学习的程序
  • Python编码问题总结

    问题一 当python中间处理非ASCII编码时 经常会出现如下错误 UnicodeDecodeError ascii codec can t decode byte 0x in position 1 ordinal not in rang
  • js对象方法Object.assign( )详解

    1 基本用法 Object assign方法用于对象的合并 将源对象 source 的所有可枚举属性 复制到目标对象 target var target a 1 var source1 b 2 var source2 c 3 Object
  • neo4j--Cypher查询调优与执行计划

    1 查询调优 1 1查询如何执行 Cypher执行引擎会将每个Cypher查询都转为一个执行计划 在执行查询时 执行计划将告知Neo4j执行什么样的操作 1 2查询性能分析 查看执行计划对查询进行分析时有两个Cypher语句可用 1 2 1
  • 关系型数据库和非关系型数据库类比

    1 关系型数据库 关系型数据库 是指采用了关系模型来组织数据的数据库 关系模型是在1970年由IBM的研究员E F Codd博士首先提出的 在之后的几十年中 关系模型的概念得到了充分的发展并逐渐成为主流数据库结构的主流模型 简单来说 关系模
  • win10 WMDC安装

    解决方案 WMDC in Windows 10 junipersys com 参考连接 Previous WMDC fixes for Windows 10 junipersys com amd64 https junipersys com
  • linux中把程序启到前台,Linux程序前台后台切换

    1 在Linux终端运行命令的时候 在命令末尾加上 符号 就可以让程序在后台运行 root Ubuntu tcpserv01 2 如果程序正在前台运行 可以使用 Ctrl z 选项把程序暂停 然后用 bg number 命令把这个程序放到后
  • 知乎爬虫经验教程

    为了完成课程论文研究 暑假写了关于知乎的爬虫 把用户主页 回答中能爬到的数据全都爬下来了 接下来 把我踩过的坑跟大家分享 希望大家少走一些弯路 1 导入一些必要的python包 其中会包括我们接下来要使用的函数 import re impo
  • 疯壳AI人脸及语音识别教程2-8WIFI-TCP网络通信

    详情地址 https fengke club GeekMart views offline ai 购买链接 https fengke club GeekMart su fKw7Nb7oC jsp 视频地址 https fengke club
  • iOS 开发中的争议(二)UI到底应该用xib/storyboard完成,还是用手写代码来完成?

    文章来源 http www devtang com blog 2015 03 22 ios dev controversy 2 参考文章 关于代码手写UI xib和StoryBoard http blog csdn net likendsl