如何熟练使用 UI 组件搭建 App 界面?

5,399 阅读4分钟

本文已参与掘金创作者训练营第三期「话题写作」赛道,详情查看:掘力计划|创作者训练营第三期正在进行,「写」出个人影响力

1. 纯代码?xib?storyboard?

  • 在 iOS 的 GUI 建设中,我们一般不外乎三种方法
  1. 纯代码
  2. xib -> 将 xml 文件转换成纯代码,来实现 GUI 建设
  3. storyboard -> 简单理解就可以是 xib 的集合
  • 纯代码:优点就是运行效率是最高的
  • xib、storyboard 都是为了提升 页面的开发效率,相对于纯代码效率相对较低,毕竟需要先加载文件有打开过IPA包的小伙伴就可以看到xib文件
  • 苹果对 storyboard 做了优化,假设多个xib文件 和一个有多个页面的sb来说,sb 的效率是更高的

我为什么要使用 storyboard

  1. 开发效率的提升(当然有更多的时间去攻坚😏)
  2. 虽然纯代码的性能优于 storyboard ,但是现在对于苹果优秀的产品和技术,这点差距可以忽略不计,所以也不用担心会过多消耗性能方面
  3. 写一个纯 storyboard 的项目,让大家看看其效果

2. SB基础知识

  • Main.Storyboard 顾名思义就是 app 进来的需要展示的页面

image.png

  • 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 和导航栏控制器;当然设置每一个控件的属性基本都在这个栏目下

image.png

设置sb 的第一个展示 controller

image.png

基本布局的认识

image.png

1. 上下左右约束、宽高、和其他控件同比、宽高比

image.png

2. 和父控件、或者其他控件都约束;上下左右边距;横向纵向对其等

image.png

3. 可以嵌入view、controller、或者取消

image.png

4. 更新一些约束、或者约束错误的时候,系统自动补全

image.png

高阶布局 嵌入

  • 在控件库里有一个container view 在纯代码里类似于 addChildController
  • 嵌入以后如下第二个图,可以自己把嵌入的view,当成一个controller来使用 ,在上一篇文章中,有一个小伙伴说静态cell必须继承 UITableViewController 不好使用,但是我们可以嵌入,就很简单啦
  • 当然嵌入的是一个controller,任何都可以嵌入的哦
  • 下第三个图,就是最终效果

image.png

image.png

image.png

高阶布局 StackView

  • 顾名思义就是像栈一样,一个一个排列控件
  • 它有好几个属性,比如横竖排列,填充方式,控件之间的距离,等等,都可以丰富布局更简单话
  • 在设置隐藏的时候,他会默认其他的显示控件优先布局,并且隐藏的控件没有预留的位置
  • 具体效果大家也可以下载demo看看哈,图片截图有不完整,见谅

image.png

image.png

image.png

高阶使用返回 A -> push -> B

  1. 我们需要在最先跳转的controller里A写返回函数,直接打就会有提示

image.png

// 这里设置了回调的数据
@IBAction func unwindToHome(_ unwindSegue: UIStoryboardSegue) {

    if let hobbyController = unwindSegue.source as? HobbyViewController {
        let str = hobbyController.hobbys[hobbyController.tableView.indexPathForSelectedRow?.row ?? 0]
        hobby.text = str

    }

}
  1. 直接拖动sb里的到exit去会显示,你在B中按住control拖动到到exit,显示我们上面实现的方法,直接获取source就是B,然后处理需要回调的数据即可

image.png

高阶用法 其他技巧

  1. 同一类的控件,我们可以选中多个,统一设置其属性
  2. 控件基本都是继承UIView,所以基本可以都同时选中设置背景色

image.png

  1. 拖动的时候,我们多个按钮拖到一个action,也可以拖到一个数组里,便捷控制

image.png

完整的demo实现了用最少的代码去实现页面功能

  • 最终的sb文件

image.png

  • 运行效果

image.png

// 判断某一个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)")
    }
}

今天大概就这些了,你的收获有多少呢?有什么想学习的可以给我留言哦~ demo地址