UIKit 是用于在 iOS 和 macOS 应用程序中构建图形界面的框架。它包含 UIView、UIViewController、控件和 Auto Layout 系统,能够创建自适应和交互式屏幕。根据 Apple Developer Documentation (2025),UIKit 包含 200 多个用于处理窗口、视图、动画、手势和文本的类 — 这是所有 iPhone 和 iPad 应用程序的基础。
要点
UIKit — 是 Apple 提供的框架,用于在 iOS、iPadOS 和 macOS(通过 Mac Catalyst)上创建和管理用户界面。它运行在 Core Animation、Core Graphics 和 Quartz Core 之上,将底层渲染抽象为高级对象 — 按钮、标签、图像和容器。UIKit 于 2007 年随 iPhone OS 1 一同出现,至今仍是与 SwiftUI 并行的 iOS 开发主要框架。
该框架遵循命令式方法:开发者创建 UIButton、UILabel、UIImageView 类的实例,设置其属性(颜色、字体、位置),并通过 addSubview 将其添加到视图层次结构中。界面的每次更改都显式执行 — 背后没有任何魔法更新。这使 UIKit 与声明式框架(如 SwiftUI)区分开来,在 SwiftUI 中,状态描述会自动重绘界面。
该框架包含多个类别的类。UIView — 所有可视组件继承自的基本元素。UIWindow — 用于在屏幕上显示视图的最高级别容器。UIViewController — 管理一组视图并对屏幕旋转、键盘出现和系统通知做出响应的控制器。UIApplication — 处理触摸和按钮按下事件的入口点。
文本使用 UILabel(静态文本)、UITextField(单行输入)、UITextView(多行输入)。按钮 — UIButton,包括系统按钮、自定义按钮和带有 SF Symbols 图标的按钮。导航 — UINavigationController、UITabBarController 和 UISplitViewController。总共 UIKit 包含 200 多个公共类。
UIKit 架构 基于层构建:每层负责其自身的显示方面。最底层是 Core Graphics — 路径、文本和图像的渲染引擎。上一层 — Core Animation,管理层的组合(CALayer)和状态之间的动画。UIKit 在其上构建了面向对象的 API:UIView、UIViewController 和 UIResponder。
每个应用程序都有一个视图层次结构(view hierarchy) — 以 UIWindow 为根的树。其下是根 UIViewController、其视图以及内部嵌套的子视图。触摸事件沿着响应者链(responder chain)传播:从最内层的视图到父视图,再到 UIApplication。如果没有对象处理触摸,则忽略该触摸。
每个 UIView 包含一个负责在屏幕上渲染像素的 CALayer 层。视图管理触摸和辅助功能,层管理图形:阴影、圆角、边框、变换。这种分离允许将繁重的图形处理转移到单独的线程(渲染服务器),而不会阻塞主线程。Apple 建议如果屏幕上需要超过 200 个视图,则直接使用 CALayer — 这可以降低 CPU 负载。
响应者链 从最先接收触摸事件的对象开始。如果它不处理该事件(touchesBegan 方法未被重写),则该事件将传递给链中的下一个响应者:next、superview、next responder、UIViewController、UIWindow、UIApplication、App Delegate。这允许在场景级别拦截全局手势和键盘事件,而无需向每个视图添加处理程序。
每个 UIViewController 都经过严格定义的事件序列。生命周期包括以下阶段:初始化、视图加载、屏幕显示、旋转时布局更新、隐藏、离开屏幕和内存释放。开发人员重写相应的方法以在每个阶段执行其代码。
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadUserProfile()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
clearCache()
}
}
在 viewDidLoad 中配置界面 — 创建子视图、设置约束、订阅委托。在 viewWillAppear 中执行显示前的操作:从网络加载新数据、更新值。viewDidDisappear — 取消通知订阅和清理临时数据的位置。在所有重写中必须调用 super,否则事件链将被中断。
在旧版本的 iOS 中,存在 viewDidUnload 方法,在内存不足时调用。从 iOS 6 开始,该方法已被删除 — 现在 UIKit 会在控制器的视图不可见时自动卸载它们。开发人员只需将所有对视图的引用声明为 weak,以便 ARC 在收到系统警告时正确释放内存。
UIKit 支持两种类型的转场:segue(通过 Storyboard)和通过 UINavigationController 进行编程导航。编程转场如下:navigationController?.pushViewController(detailVC, animated: true)。此时 detailVC 的生命周期正常进行 — viewDidLoad 被调用一次,viewWillAppear — 每次显示时调用。
Auto Layout — 是一种基于数学关系(约束)的元素定位系统。开发者无需使用固定的 X 和 Y 坐标,而是描述规则:「按钮位于标签右侧,间距 16pt」或「视图在屏幕宽度上拉伸,左右边距 20pt」。系统在运行时求解生成的方程组,使界面适应任何屏幕尺寸。
约束可以在 Interface Builder(通过拖放)或以编程方式在 Swift 中设置。每个约束都是 NSLayoutConstraint 类的实例,参数包括:firstItem、firstAttribute、relation、secondItem、secondAttribute、multiplier、constant。约束通过 isActive = true 或批量通过 NSLayoutConstraint.activate() 激活。
随着 iPhone X(2017)的推出,Apple 引入了 Safe Area — 屏幕中没有刘海、圆角和 home 条指示器的区域。约束应绑定到 view.safeAreaLayoutGuide,而不是 view。Layout Margins 添加视图的内部边距,默认根据上下文为 8pt 或 16pt。使用 safeAreaLayoutGuide 可确保在所有 iPhone 和 iPad 上正确显示。
Auto Layout 支持通过更改约束的常量来实现动画。只需更新约束的 constant 并在动画块中调用带有 layoutIfNeeded 的 UIView.animate。系统会平滑地重新计算层次结构中所有视图的位置。此技术用于可展开块、自适应键盘面板和屏幕方向更改。
UITableView 和 UICollectionView — UIKit 中用于显示列表和网格的两个强大工具。UITableView 适用于单列垂直列表(聊天、设置、新闻源)。UICollectionView — 适用于网格、水平列表、轮播和自定义布局(图库、产品、日历)。两个类都使用委托模式来分离数据和外观。
数据源是 UITableViewDataSource 协议,包含必需的方法 numberOfRowsInSection 和 cellForRowAt。委托 UITableViewDelegate 处理单元格点击、行高和滚动事件。重用标识符机制会重用已离开屏幕的单元格,这对于大型列表的性能至关重要。
class ContactsViewController: UITableViewController {
private let contacts = ["安娜", "鲍里斯", "维克多"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self,
forCellReuseIdentifier: "cell")
}
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath)
var content = cell.defaultContentConfiguration()
content.text = contacts[indexPath.row]
cell.contentConfiguration = content
return cell
}
}
示例显示了一个用于显示字符串数组的最小控制器。单元格通过 UIListContentConfiguration 配置 — 这是一种现代 API(iOS 14+),取代了已弃用的 textLabel 和 detailTextLabel。在 viewDidLoad 中注册单元格类是强制性的,否则应用程序将在运行时崩溃并抛出异常。
从 iOS 13 开始,Apple 推荐使用 UICollectionViewCompositionalLayout 来构建复杂布局。开发者以声明方式描述节、组、元素及其大小 — 获得具有任意几何形状的网格:条带、2x2 网格、轮播、装饰。组合布局已在所有新项目中取代了已弃用的 UICollectionViewFlowLayout。结合 DiffableDataSource,集合的更新简化为一次 apply(snapshot) 调用,并且更改的动画会自动执行。
以下是在实际任务中使用 UIKit 的两个实际示例:创建具有阴影和圆角的自定义视图,以及处理滑动手势以从列表中删除元素。
extension UIView {
func applyCardStyle() {
layer.cornerRadius = 12
layer.shadowOpacity = 0.15
layer.shadowRadius = 8
layer.shadowOffset = CGSize(width: 0, height: 2)
layer.masksToBounds = false
}
}
@objc private func handleSwipe(_ gesture: UISwipeGestureRecognizer) {
guard let swipedView = gesture.view else { return }
UIView.animate(withDuration: 0.3) {
swipedView.alpha = 0
swipedView.transform = CGAffineTransform(translationX: 300, y: 0)
} completion: { _ in
swipedView.removeFromSuperview()
}
}
applyCardStyle 扩展为任何视图添加阴影和圆角 — 适用于产品卡片、个人资料和通知。带有动画的 handleSwipe 方法在用户向右滑动时删除该元素。处理程序通过 addGestureRecognizer 添加到视图中,配置为 UISwipeGestureRecognizer(direction: .right)。设置 masksToBounds = false 很重要,这样阴影就不会被视图边界裁剪。
对于更复杂的界面,请使用 UIStackView — 一个自动水平或垂直分布嵌套视图的容器。Stack View 简化了布局:无需为每个元素设置约束,只需为堆栈本身设置一个约束即可。
常见问题
Frame — 在父视图坐标中的矩形(位置 + 大小)。Bounds — 在视图自身坐标中的矩形(始终从 0,0 开始)。Frame 在旋转和缩放时改变,bounds — 不变。
UIKit 会自动卸载隐藏控制器的视图。开发者只需将视图属性声明为 weak var,以便 ARC 在收到系统警告时释放内存。
对于新项目,Apple 推荐使用 SwiftUI。如果项目基于 UIKit — 对单个屏幕使用 XIB 或通过 SnapKit 使用编程布局。Storyboard 会产生合并冲突并减慢构建速度。
使用带有 traitCollection 支持的 UIColor:UIColor { $0.userInterfaceStyle == .dark ? ... : ... }。在 Info.plist 中使用 UIUserInterfaceStyle 键激活深色模式。
UIStackView 根据对齐方式、分布和间距自动计算嵌套视图的位置和大小。这可将约束代码减少 60–80%,并简化对不同屏幕的适配。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。