iOS UI 框架详解
概述
iOS 开发中主要使用两个 UI 框架:
- UIKit --- 基于 Objective-C 的经典框架,自 iOS 2.0 起存在
- SwiftUI --- Apple 2019 年推出的声明式框架,采用 Swift 语言
一、UIKit
1.1 核心概念
| 概念 | 说明 |
|---|---|
| UIView | 所有可视控件的基类 |
| UIViewController | 控制器,管理视图生命周期 |
| UIWindow | 应用的窗口容器,连接 MVC 模式 |
| Storyboard / XIB | 可视化界面设计文件 |
1.2 Storyboard 与 UIViewController 的关系
AppDelegate
└── UIWindow
└── UINavigationController / UITabBarController (可选)
└── UIViewController (通过 Storyboard 或代码创建)
└── UIView (subviews)
- Storyboard 是 XML 格式的可视化文件,在一个文件中描述多个页面和它们的跳转关系
- UIViewController 是视图的「控制器」,负责处理视图的生命周期、数据传递、用户交互
- 两者通过
instantiateViewController(withIdentifier:)或 Segue 关联
1.3 常用组件
容器类
UIView--- 基础视图UIScrollView--- 滚动视图UITableView/UICollectionView--- 列表/网格UITabBarController/UINavigationController--- 导航结构
控件类
UILabel--- 文本标签UIButton--- 按钮UITextField/UITextView--- 输入框UIImageView--- 图片UISwitch/UISlider/UISegmentedControl--- 交互控件UIActivityIndicatorView--- 加载指示器UIProgressView--- 进度条
布局
NSLayoutConstraint+Anchor语法Masonry(第三方布局库)
1.4 使用场景
- 需要兼容 iOS 12 及更早版本
- 项目使用 Objective-C 开发
- 需要精细控制性能和内存
- 已有大量基于 UIKit 的存量项目
- 需要复杂的手势和自定义动画
- 系统级功能或深度集成第三方 SDK
1.5 注意事项
- 内存管理 :手动管理
strong/weak引用,需注意循环引用 - 布局适配 :需要处理多尺寸屏幕,常用
Autolayout - 生命周期 :熟悉
viewDidLoad、viewWillAppear、viewDidAppear等方法 - 线程安全:UI 操作必须在主线程执行
- Storyboard 冲突:多人协作时 Storyboard XML 冲突较为棘手
1.6 简单示例
纯代码方式
swift
class MyViewController: UIViewController {
private let label = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
label.text = "Hello UIKit"
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
}
Storyboard + Segue
- 在 Storyboard 中拖入
UIViewController - 设置 Storyboard ID 为
"MyVC" - 代码中跳转:
swift
let vc = storyboard?.instantiateViewController(withIdentifier: "MyVC")
navigationController?.pushViewController(vc!, animated: true)
二、SwiftUI
2.1 核心概念
| 概念 | 说明 |
|---|---|
| @State | 视图内部状态管理 |
| @Binding | 双向绑定 |
| @ObservedObject | 引用类型Observable对象 |
| @Environment | 环境值注入 |
| ViewBuilder | 声明式视图构造 |
| Modifier | 链式调用修改视图属性 |
2.2 View 与 UIViewController 的对应关系
SwiftUI App
└── NavigationStack / TabView
└── 自定义 View (struct)
└── 子 View
- SwiftUI 无 UIViewController :通过
NavigationStack等容器替代导航控制器 - View 是值类型 (struct):每次状态变更可能整体重建
- 数据流是单向的:@State → View 渲染 → 用户交互 → @State 更新
2.3 常用组件
基础
Text,Image,Color,Circle,Rectangle
容器
VStack,HStack,ZStackList,Form,ScrollViewNavigationStack,TabView
控件
Button,TextField,TextEditorToggle,Slider,Picker,DatePickerImage,AsyncImageProgressView,ProgressView
手势与动画
.gesture(),.animation(),.transition()
2.4 使用场景
- 新建 Swift 项目,目标 iOS 13+
- 追求简洁的声明式代码
- 快速原型开发和迭代
- 跨平台布局(iOS、iPadOS、macOS)
- 实时预览(Preview in Xcode)
- 配合 Combine 处理响应式数据流
2.5 注意事项
- iOS 13 兼容 :部分特性(如
NavigationStack)需要 iOS 16+ - 性能 :复杂视图下避免不必要的
@State更新 - 调试:编译错误信息不够直观,堆栈较长
- 与 UIKit 混用 :可通过
UIViewControllerRepresentable包装 UIKit 控件 - 第三方库:部分老牌 UIKit 库无 SwiftUI 支持
- 状态管理:需要理解 Swift 的引用语义(class vs struct)
2.6 简单示例
swift
struct ContentView: View {
@State private var text = "Hello SwiftUI"
var body: some View {
VStack(spacing: 20) {
Text(text)
.font(.largeTitle)
Button("Tap Me") {
text = "Button Tapped!"
}
}
.padding()
}
}
三、对比分析
3.1 难度对比
| 维度 | UIKit | SwiftUI |
|---|---|---|
| 入门门槛 | 较高(需理解 MVC、生命周期) | 较低(声明式语法直观) |
| 代码量 | 较多(需要手动创建视图和布局) | 较少(声明式 DSL) |
| 布局语法 | Autolayout,约束较多 | 栈容器 + Modifier,简洁 |
| 调试难度 | 较低,熟悉的断点调试 | 较高,堆栈不直观 |
| 自定义能力 | 极高,可继承任何类 | 受限于框架提供的组件 |
3.2 性能对比
| 维度 | UIKit | SwiftUI |
|---|---|---|
| 启动时间 | 更快(直接操作原生对象) | 略慢(需编译 DSL) |
| 运行时开销 | 低(成熟优化) | 较低但复杂视图会有额外比较开销 |
| 内存 | 需手动管理 | 自动管理,但 struct 拷贝需注意 |
| 列表滚动 | 高度优化(cell 复用) | LazyVStack 同样高效 |
3.3 使用量与存量现状
| 维度 | UIKit | SwiftUI |
|---|---|---|
| 市场占有率 | 仍占主导,尤其企业级应用 | 持续增长,新项目采用率高 |
| 开源生态 | 极其丰富(Masonry、SnapKit 等) | 逐步完善,部分库仍在迁移 |
| 招聘需求 | 仍为主体 | 快速增长 |
| Apple 推进方向 | 维护但不新增大功能 | 持续投入(SwiftUI 每年都有新特性) |
3.4 技术特点对比
| 维度 | UIKit | SwiftUI |
|---|---|---|
| 架构模式 | MVC(事实标准) | MVVM(原生支持) |
| 编程范式 | 命令式 | 声明式 |
| 状态管理 | 手动(Delegate / Notification / Closure) | 响应式(@State / @Binding / @ObservedObject) |
| 布局方式 | Frame + Autolayout | 栈容器(VStack/HStack/ZStack)+ Modifier |
| 预览 | 需运行模拟器 | Xcode Canvas 实时预览 |
| Storyboard | 支持 | 不支持(代码声明) |
| 跨平台 | 仅 iOS | 支持 iOS/iPadOS/macOS/visionOS |
3.5 互操作
SwiftUI 中使用 UIKit
swift
struct MyView: View {
var body: some View {
UIViewControllerRepresentable wrapsUIKit()
}
}
UIKit 中使用 SwiftUI
swift
let swiftUIView = UIHostingController(rootView: MySwiftUIView())
addChild(swiftUIView)
swiftUIView.view.frame = view.bounds
view.addSubview(swiftUIView.view)
swiftUIView.didMove(toParent: self)
四、总结建议
| 场景 | 推荐框架 |
|---|---|
| 新建个人项目 / 快速原型 | SwiftUI |
| 企业级存量项目维护 | UIKit |
| 需要精细性能优化 | UIKit |
| Objective-C 项目 | UIKit |
| 跨 Apple 平台(macOS + iOS) | SwiftUI |
| 复杂自定义动画/手势 | UIKit |
| 需要大量第三方库支持 | UIKit |
| 学习 / 教学 / 面试准备 | 两者皆学,以 UIKit 为主 |
趋势
- Apple 官方明确将 SwiftUI 作为未来方向
- UIKit 不会消失,但新功能会以 SwiftUI 为先
- 建议新项目优先考虑 SwiftUI,同时保持对 UIKit 的了解(便于维护旧项目和理解底层原理)
整理日期:2026/05/11