本文已参与掘金创作者训练营第三期「话题写作」赛道,详情查看:掘力计划|创作者训练营第三期正在进行,「写」出个人影响力。
1. 纯代码?xib?storyboard?
- 在 iOS 的 GUI 建设中,我们一般不外乎三种方法
- 纯代码
- xib -> 将 xml 文件转换成纯代码,来实现 GUI 建设
- storyboard -> 简单理解就可以是 xib 的集合
- 纯代码:优点就是运行效率是最高的
- xib、storyboard 都是为了提升 页面的开发效率,相对于纯代码效率相对较低,毕竟需要先加载文件有打开过IPA包的小伙伴就可以看到xib文件
- 苹果对 storyboard 做了优化,假设多个xib文件 和一个有多个页面的sb来说,sb 的效率是更高的
我为什么要使用 storyboard
- 开发效率的提升(当然有更多的时间去攻坚😏)
- 虽然纯代码的性能优于 storyboard ,但是现在对于苹果优秀的产品和技术,这点差距可以忽略不计,所以也不用担心会过多消耗性能方面
- 写一个纯 storyboard 的项目,让大家看看其效果
2. SB基础知识
- Main.Storyboard 顾名思义就是 app 进来的需要展示的页面
- UIStoryboard 只有两个初始化方法
// 初始化方法 name: sb 的名字,不用写后缀、Bundle 为 nil 就是默认的 main
public init(name: String, bundle storyboardBundleOrNil: Bundle?)
// 获取指定的第一次进去显示的 sb 的 controller
open func instantiateInitialViewController() -> UIViewController?
// 获取指定 StoryboardID 的 controller
open func instantiateViewController(withIdentifier identifier: String) -> UIViewController
- UIStoryboardSegue 顾名思义就是链接 UIStoryboard 里的 controller 的
- 最主要的就是以下三个属性;初始化方法就是自己可以用代码创建一个 segue 链接
// sb 里 segue 的 id
open var identifier: String? { get }
// 从哪个 controller 跳转
open var source: UIViewController { get }
// 跳转到哪个 controller
open var destination: UIViewController { get }
- UIStoryboardUnwindSegueSource 可以简单理解为回退
3. 多 SB 结合,使用技巧、注意事项
在xib 中快速嵌套 tabbar controller 和导航栏控制器;当然设置每一个控件的属性基本都在这个栏目下
设置sb 的第一个展示 controller
基本布局的认识
1. 上下左右约束、宽高、和其他控件同比、宽高比
2. 和父控件、或者其他控件都约束;上下左右边距;横向纵向对其等
3. 可以嵌入view、controller、或者取消
4. 更新一些约束、或者约束错误的时候,系统自动补全
高阶布局 嵌入
- 在控件库里有一个container view 在纯代码里类似于 addChildController
- 嵌入以后如下第二个图,可以自己把嵌入的view,当成一个controller来使用 ,在上一篇文章中,有一个小伙伴说静态cell必须继承 UITableViewController 不好使用,但是我们可以嵌入,就很简单啦
- 当然嵌入的是一个controller,任何都可以嵌入的哦
- 下第三个图,就是最终效果
高阶布局 StackView
- 顾名思义就是像栈一样,一个一个排列控件
- 它有好几个属性,比如横竖排列,填充方式,控件之间的距离,等等,都可以丰富布局更简单话
- 在设置隐藏的时候,他会默认其他的显示控件优先布局,并且隐藏的控件没有预留的位置
- 具体效果大家也可以下载demo看看哈,图片截图有不完整,见谅
高阶使用返回 A -> push -> B
- 我们需要在最先跳转的controller里A写返回函数,直接打就会有提示
// 这里设置了回调的数据
@IBAction func unwindToHome(_ unwindSegue: UIStoryboardSegue) {
if let hobbyController = unwindSegue.source as? HobbyViewController {
let str = hobbyController.hobbys[hobbyController.tableView.indexPathForSelectedRow?.row ?? 0]
hobby.text = str
}
}
- 直接拖动sb里的到exit去会显示,你在B中按住control拖动到到exit,显示我们上面实现的方法,直接获取source就是B,然后处理需要回调的数据即可
高阶用法 其他技巧
- 同一类的控件,我们可以选中多个,统一设置其属性
- 控件基本都是继承UIView,所以基本可以都同时选中设置背景色
- 拖动的时候,我们多个按钮拖到一个action,也可以拖到一个数组里,便捷控制
完整的demo实现了用最少的代码去实现页面功能
- 最终的sb文件
- 运行效果
// 判断某一个sb里的id 不满足跳转不让跳转
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "" {
return false
}
return true
}
// 跳转的时候,如需要传递参数,可以在此方法
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let controller = segue.destination as? LayoutViewController {
print("todo...\(controller.description)")
}
}