需求:使用 runtime 拦截系统方法,改变 UIView 的背景颜色。
为什么这么做?假如很多界面都是使用同一种颜色,之后突然有需求,把颜色全部改成另一种颜色,如果一个一个界面的去改,很浪费时间,这个时候 runtime 就起到了很好的作用,用它来拦截系统设置视图背景颜色的方法,改成自己想要的颜色。
- 思路及步骤
1.创建一个 UIView 的分类,在 .m 文件导入 runtime 的头文件。
2.实现 load 方法。
3.自定义设置背景颜色的方法,判断是否是需要改变的颜色
4.获取系统方法
5.获取自定义方法
6.交换它们之间的 IMP 方法
先来看没有添加分类时候的效果,设置视图控制器的背景颜色为黄色。
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.yellowColor;
}
@end
运行起来没什么改变,还是黄色。
下面开始按上面的步骤实现,这里还是直接贴代码吧,代码很少。
//
// UIView+Swizzing.m
// 01-RuntimeSendMessage
//
// Created by Mac on 2019/10/31.
// Copyright © 2019 Mac. All rights reserved.
//
#import "UIView+Swizzing.h"
#import <objc/runtime.h>
@implementation UIView (Swizzing)
+ (void)load {
// 1.获取系统设置背景颜色的方法
Method m1 = class_getInstanceMethod(self, @selector(setBackgroundColor:));
// 2.获取自定义设置背景颜色的方法
Method m2 = class_getInstanceMethod(self, @selector(fb_setBackgroundColor:));
// 3.交换它们之间的 IMP 方法
method_exchangeImplementations(m1, m2);
}
/// 自定义设置背景颜色的方法
/// @param color UIColor
- (void)fb_setBackgroundColor:(UIColor *)color {
// 如果颜色为 yellowColor ,就改变成红色
if (color == [UIColor yellowColor]) {
[self fb_setBackgroundColor:[UIColor redColor]];
}
}
@end
添加完之后,再运行,看一下效果,发现背景颜色果然被改变了!
至此,拦截系统方法,交换设置背景颜色的方法就实现了。