UIKit 是 iOS/iPadOS 开发的核心 UI 框架,基于 Objective-C 构建,封装了所有可视化界面、交互、布局、渲染相关的能力,是构建 iOS 应用的基础。以下从「基础架构→核心组件→布局→事件→渲染→适配→优化→调试」全维度拆解 UIKit 知识体系,覆盖开发全场景。
一、UIKit 基础核心(框架基石)
1. UIKit 定位与依赖
- 基于 Foundation(数据处理:NSString/NSDictionary 等);
- 依赖 Core Graphics(绘图)、Core Animation(动画/渲染)、Core Text(文本排版);
- 兼容 AppKit(macOS)部分逻辑,但针对移动设备做了轻量化适配。
2. 应用入口与生命周期
(1)应用级入口(UIApplication)
UIApplication 是应用的「单例管家」,管理应用生命周期、事件分发、状态栏、URL 跳转等:
// 获取应用单例
UIApplication *app = [UIApplication sharedApplication];
// 设置状态栏样式(iOS 13+ 需在 Info.plist 配置 View controller-based status bar appearance = NO)
app.statusBarStyle = UIStatusBarStyleLightContent;
// 打开URL
[app openURL:[NSURL URLWithString:@"https://www.apple.com"] options:@{} completionHandler:nil];
(2)应用代理(UIApplicationDelegate / SceneDelegate)
| 核心生命周期方法(UIApplicationDelegate) |
说明 |
application:didFinishLaunchingWithOptions: |
应用启动完成(初始化根控制器) |
applicationDidBecomeActive: |
应用进入前台(可交互) |
applicationWillResignActive: |
应用退至后台(如来电、下拉通知) |
applicationDidEnterBackground: |
应用完全后台(需保存数据) |
applicationWillEnterForeground: |
应用即将前台(恢复界面) |
applicationWillTerminate: |
应用即将退出(最后清理) |
(3)UIViewController 生命周期(核心)
控制器是「视图的管理者」,其生命周期决定了视图的创建/销毁,OC 核心方法如下:
@interface ViewController ()
@end
@implementation ViewController
// 1. 初始化(代码创建时调用)
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// 初始化数据、配置
}
return self;
}
// 2. 加载视图(视图首次创建,懒加载)
- (void)loadView {
// 手动创建根视图(若不用XIB/Storyboard)
self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.view.backgroundColor = [UIColor whiteColor];
}
// 3. 视图加载完成(初始化控件、布局)
- (void)viewDidLoad {
[super viewDidLoad];
// 核心初始化逻辑(仅执行一次)
}
// 4. 视图即将显示(每次显示前调用,如跳转返回)
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 更新界面数据、刷新布局
}
// 5. 视图已显示(可执行动画、网络请求)
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
// 6. 视图即将隐藏
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// 暂停动画、移除监听
}
// 7. 视图已隐藏
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
// 8. 内存警告(释放非必要资源)
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
// 9. 视图销毁(控制器释放前)
- (void)dealloc {
// 移除通知、释放强引用(避免内存泄漏)
NSLog(@"控制器销毁");
}
@end
3. 响应者体系(UIResponder)
UIKit 所有可交互元素都继承自 UIResponder(响应者),构成「响应者链」处理事件(触摸、手势、键盘等):
// 触摸事件
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
// 成为第一响应者(如输入框唤起键盘)
- (BOOL)becomeFirstResponder;
// 放弃第一响应者(如输入框收起键盘)
- (BOOL)resignFirstResponder;
1. 系统通过 hitTest:withEvent: 从父视图到子视图查找「最顶层可交互视图」;
2. 找到后调用该视图的事件方法(如 touchesBegan:);
3. 若该视图不处理,事件沿响应者链向上传递(子视图→父视图→控制器→Window→Application)。
4. UIView 核心(视图基础)
UIView 是所有可视化元素的基类,负责展示、布局、事件接收,核心属性/方法:
| 核心属性 |
说明 |
frame |
相对于父视图的位置+尺寸(CGRect),决定视图在父视图中的显示区域 |
bounds |
自身坐标系的位置+尺寸(origin 默认 (0,0),修改会偏移子视图) |
center |
相对于父视图的中心点坐标(CGPoint) |
transform |
形变(缩放、旋转、平移,基于 center) |
backgroundColor |
背景色(UIColor) |
alpha |
透明度(0~1,0 完全透明,1 不透明) |
hidden |
是否隐藏(YES 隐藏,不参与布局/事件) |
clipsToBounds |
是否裁剪超出自身边界的子视图(YES 裁剪) |
layer |
底层 CALayer(负责渲染,UIView 是 CALayer 的封装) |
二、UIKit 核心组件(常用控件)
1. 基础交互控件
| 控件类 |
用途 |
核心 OC 示例 |
UILabel |
文本展示 |
UILabel *label = [[UILabel alloc] init]; label.text = @"Hello UIKit"; label.font = [UIFont systemFontOfSize:16]; |
UIButton |
按钮(点击交互) |
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem]; [btn setTitle:@"点击" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside]; |
UITextField |
单行文本输入 |
UITextField *tf = [[UITextField alloc] init]; tf.placeholder = @"请输入内容"; tf.keyboardType = UIKeyboardTypeDefault; |
UITextView |
多行文本输入/展示 |
UITextView *tv = [[UITextView alloc] init]; tv.text = @"多行文本"; tv.editable = YES; |
UIImageView |
图片展示 |
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon"]]; iv.contentMode = UIViewContentModeScaleAspectFit; |
UISwitch |
开关(开/关) |
UISwitch *sw = [[UISwitch alloc] init]; sw.on = YES; [sw addTarget:self action:@selector(switchChange:) forControlEvents:UIControlEventValueChanged]; |
UISlider |
滑块(数值调节) |
UISlider *slider = [[UISlider alloc] init]; slider.minimumValue = 0; slider.maximumValue = 100; slider.value = 50; |
UISegmentedControl |
分段选择器 |
UISegmentedControl *seg = [[UISegmentedControl alloc] initWithItems:@[@"选项1", @"选项2"]]; seg.selectedSegmentIndex = 0; |
2. 列表/集合控件(高频)
(1)UITableView(列表)
核心是「数据源+代理」模式,支持单行列表展示,OC 核心实现:
@interface TableViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSArray *dataArray;
@end
@implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.dataArray = @[@"行1", @"行2", @"行3"];
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tableView.dataSource = self;
self.tableView.delegate = self;
// 注册单元格(复用)
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cellID"];
[self.view addSubview:self.tableView];
}
// 数据源:行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataArray.count;
}
// 数据源:单元格内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
cell.textLabel.text = self.dataArray[indexPath.row];
return cell;
}
// 代理:单元格点击
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"点击第%ld行", indexPath.row);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
@end
(2)UICollectionView(集合视图)
支持网格、瀑布流等自定义布局,OC 核心实现:
@interface CollectionViewController () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, strong) UICollectionView *collectionView;
@end
@implementation CollectionViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 布局配置(流式布局)
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(100, 100); // 单元格尺寸
layout.minimumInteritemSpacing = 10; // 列间距
layout.minimumLineSpacing = 10; // 行间距
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellID"];
[self.view addSubview:self.collectionView];
}
// 数据源:单元格数量
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 12;
}
// 数据源:单元格内容
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellID" forIndexPath:indexPath];
cell.backgroundColor = [UIColor lightGrayColor];
return cell;
}
@end
3. 容器控件(页面导航/布局)
| 控件类 |
用途 |
核心 OC 示例 |
UIScrollView |
可滚动视图(基础) |
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; scrollView.contentSize = CGSizeMake(375, 1000); scrollView.showsVerticalScrollIndicator = YES; |
UINavigationController |
导航控制器(页面栈) |
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]]; nav.navigationBar.barTintColor = [UIColor blueColor]; |
UITabBarController |
标签栏控制器(底部切换) |
UITabBarController *tabBarVC = [[UITabBarController alloc] init]; tabBarVC.viewControllers = @[nav1, nav2]; tabBarVC.tabBar.tintColor = [UIColor redColor]; |
UIPageViewController |
分页控制器(左右滑切换) |
UIPageViewController *pageVC = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; |
4. 弹窗/提示控件
| 控件类 |
用途 |
核心 OC 示例 |
UIAlertController |
弹窗(警告/操作) |
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"确定删除?" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {}]]; [self presentViewController:alert animated:YES completion:nil]; |
UIActivityIndicatorView |
加载指示器 |
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithStyle:UIActivityIndicatorViewStyleLarge]; [indicator startAnimating]; |
UIRefreshControl |
下拉刷新 |
UIRefreshControl *refresh = [[UIRefreshControl alloc] init]; [refresh addTarget:self action:@selector(refreshData:) forControlEvents:UIControlEventValueChanged]; self.tableView.refreshControl = refresh; |
三、布局体系(UIKit 核心能力)
1. 基础布局(Frame/Bounds/Center)
手动控制视图位置,适合简单布局:
UIView *boxView = [[UIView alloc] init];
boxView.frame = CGRectMake(20, 100, 100, 100); // x:20, y:100, 宽100, 高100
boxView.center = CGPointMake(187.5, 150); // 中心点(父视图宽375,水平居中)
boxView.bounds = CGRectMake(-10, -10, 100, 100); // 自身坐标系偏移,子视图会右移/下移10pt
[self.view addSubview:boxView];
2. 自动布局(Auto Layout)
通过「约束」定义视图关系,适配多屏幕,OC 原生实现:
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
btn.translatesAutoresizingMaskIntoConstraints = NO; // 必须关闭自动掩码
[self.view addSubview:btn];
// 创建约束:按钮左/右间距20pt,顶部100pt,高度44pt
NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:btn attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:20];
NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:btn attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:-20];
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:btn attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:100];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:btn attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:44];
// 添加约束
[self.view addConstraints:@[leading, trailing, top]];
[btn addConstraint:height];
Masonry 封装(OC 主流)
#import "Masonry.h"
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.equalTo(self.view).offset(20);
make.trailing.equalTo(self.view).offset(-20);
make.top.equalTo(self.view).offset(100);
make.height.mas_equalTo(44);
}];
3. 尺寸适配(Size Classes + Trait Collection)
适配多设备/横竖屏,OC 实现:
// 监听尺寸类变化
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
// 宽屏(如iPad/手机横屏)
if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular) {
[self.btn mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(60);
}];
} else { // 窄屏(手机竖屏)
[self.btn mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(44);
}];
}
[self.view layoutIfNeeded];
}
4. 安全区域(Safe Area)
适配刘海屏/底部横条,OC 实现:
// 约束适配安全区域
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.equalTo(self.view.safeAreaLayoutGuide).offset(20);
make.trailing.equalTo(self.view.safeAreaLayoutGuide).offset(-20);
make.top.equalTo(self.view.safeAreaLayoutGuide).offset(20);
}];
四、事件处理(交互核心)
1. 触摸事件(UITouch)
自定义视图触摸处理:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view]; // 触摸点坐标
NSLog(@"触摸位置:%@", NSStringFromCGPoint(point));
}
2. 手势识别(UIGestureRecognizer)
OC 核心示例(点击/长按/滑动):
// 点击手势
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
tap.numberOfTapsRequired = 1; // 点击次数
[self.view addGestureRecognizer:tap];
// 长按手势
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGesture:)];
longPress.minimumPressDuration = 1.0; // 长按时长(秒)
[self.view addGestureRecognizer:longPress];
// 滑动手势
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
swipe.direction = UISwipeGestureRecognizerDirectionRight; // 滑动方向
[self.view addGestureRecognizer:swipe];
3. 响应者链拦截(hitTest:withEvent:)
自定义视图可点击区域:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
// 若视图隐藏/透明/不可交互,不响应事件
if (self.hidden || self.alpha <= 0.01 || !self.userInteractionEnabled) {
return nil;
}
// 检查点是否在视图范围内
if (![self pointInside:point withEvent:event]) {
return nil;
}
// 优先返回子视图(倒序遍历,顶层视图优先)
for (UIView *subview in [self.subviews reverseObjectEnumerator]) {
CGPoint subPoint = [subview convertPoint:point fromView:self];
UIView *hitView = [subview hitTest:subPoint withEvent:event];
if (hitView) {
return hitView;
}
}
return self;
}
五、渲染与动画
1. 视图渲染(CALayer + drawRect:)
(1)CALayer 基础(UIView 底层渲染)
// 给视图添加圆角(通过layer)
self.view.layer.cornerRadius = 10;
self.view.layer.masksToBounds = YES; // 裁剪圆角
self.view.layer.borderWidth = 1.0;
self.view.layer.borderColor = [UIColor grayColor].CGColor;
// 阴影(注意:masksToBounds=NO 才生效)
self.view.layer.shadowColor = [UIColor blackColor].CGColor;
self.view.layer.shadowOffset = CGSizeMake(2, 2);
self.view.layer.shadowOpacity = 0.5;
self.view.layer.shadowRadius = 4;
(2)自定义绘制(drawRect:)
- (void)drawRect:(CGRect)rect {
// 获取绘图上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 设置画笔颜色
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
// 设置线宽
CGContextSetLineWidth(ctx, 2.0);
// 绘制矩形
CGContextAddRect(ctx, CGRectMake(20, 20, 100, 100));
// 绘制路径
CGContextStrokePath(ctx);
}
2. UIView 动画(基础动画)
// 平移动画
[UIView animateWithDuration:0.3 animations:^{
self.btn.center = CGPointMake(self.btn.center.x + 100, self.btn.center.y);
} completion:^(BOOL finished) {
// 动画完成回调
}];
// 组合动画(缩放+旋转)
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.btn.transform = CGAffineTransformMakeScale(1.5, 1.5); // 缩放
self.btn.transform = CGAffineTransformRotate(self.btn.transform, M_PI_4); // 旋转45度
} completion:nil];
// 转场动画
[UIView transitionWithView:self.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
[self.view addSubview:self.newView];
} completion:nil];
3. Core Animation(核心动画,底层)
// 关键帧动画(路径动画)
CAKeyframeAnimation *keyFrame = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 20, 100);
CGPathAddLineToPoint(path, NULL, 355, 100);
CGPathAddLineToPoint(path, NULL, 355, 500);
CGPathAddLineToPoint(path, NULL, 20, 500);
keyFrame.path = path;
keyFrame.duration = 2.0;
[self.btn.layer addAnimation:keyFrame forKey:@"keyFrameAnimation"];
六、多态适配(暗黑模式/动态字体)
1. 暗黑模式(iOS 13+)
// 动态颜色(适配暗黑/浅色模式)
UIColor *dynamicColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
return [UIColor whiteColor]; // 暗黑模式
} else {
return [UIColor blackColor]; // 浅色模式
}
}];
self.view.backgroundColor = dynamicColor;
// 监听模式变化
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
// 更新颜色/图片
self.label.textColor = dynamicColor;
}
}
2. 动态字体(适配字体大小)
// 动态字体(跟随系统字体大小)
UIFont *dynamicFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
self.label.font = dynamicFont;
// 监听字体大小变化
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fontSizeChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil];
七、性能优化
1. 列表优化(UITableView/UICollectionView)
2. 渲染优化
-
避免频繁调用 setNeedsLayout/layoutIfNeeded;
-
自定义绘制优先用 CALayer 而非 drawRect:;
-
开启光栅化(layer.shouldRasterize = YES,仅适合静态视图);
-
减少透明视图(alpha < 1 会触发离屏渲染)。
3. 内存优化
-
避免循环引用(block 中用 weakSelf);
-
图片压缩(UIImageJPEGRepresentation/UIImagePNGRepresentation);
-
及时释放强引用(dealloc 中移除通知/定时器);
-
懒加载控件(避免一次性创建大量视图)。
八、调试工具
1. Xcode 内置工具
- Core Animation:检测离屏渲染、帧率;
- Time Profiler:检测卡顿;
- Allocations:检测内存泄漏;
2. 约束冲突排查
-
控制台日志中定位「Unable to simultaneously satisfy constraints」;
-
降低非核心约束优先级(constraint.priority = UILayoutPriorityDefaultHigh);
-
动态激活/禁用约束(constraint.active = YES/NO)。
九、进阶特性
1. 自定义控件
继承 UIView/UIControl 实现自定义交互控件:
@interface CustomControl : UIControl
@property (nonatomic, assign) CGFloat progress;
@end
@implementation CustomControl
- (void)setProgress:(CGFloat)progress {
_progress = progress;
[self setNeedsDisplay]; // 触发重绘
}
- (void)drawRect:(CGRect)rect {
// 绘制进度条
CGRect progressRect = CGRectMake(0, 0, rect.size.width * self.progress, rect.size.height);
[[UIColor blueColor] setFill];
UIRectFill(progressRect);
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
self.progress = point.x / self.bounds.size.width;
[self sendActionsForControlEvents:UIControlEventValueChanged]; // 触发值变化事件
}
@end
2. 文本排版(NSAttributedString)
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:@"富文本示例"];
// 设置字体
[attStr addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:18] range:NSMakeRange(0, 3)];
// 设置颜色
[attStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 3)];
// 设置下划线
[attStr addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(3, 2)];
self.label.attributedText = attStr;
十、最佳实践
-
MVC 分层:控制器仅负责逻辑调度,视图仅负责展示,模型仅负责数据;
-
控件封装:将重复的控件逻辑封装为分类/子类(如 UIButton+Custom);
-
兼容性处理:通过 @available 适配不同 iOS 版本:
if (@available(iOS 13.0, *)) {
// iOS 13+ 逻辑
} else {
// 低版本逻辑
}
-
避免生命周期陷阱:viewDidLoad 仅初始化,viewWillAppear 处理每次显示的逻辑;
-
响应链优化:减少不必要的 userInteractionEnabled = NO,避免事件传递卡顿。
总结
UIKit 是 iOS 开发的「基石框架」,核心围绕「视图(UIView)- 控制器(UIViewController)- 事件(UIResponder)」展开,掌握「布局体系」「事件处理」「渲染优化」是关键。实际开发中,优先用 Masonry 简化 Auto Layout,结合 Size Classes/暗黑模式适配多场景,通过 Instruments 定位性能问题,可高效构建稳定、适配性强的 iOS 界面。