KMNavigationBarTransition是美团开发的专为定制UINavigationBar的样式,在不同的控制器中实现UINavigationBar不同地样式,使每个控制器实现我们想要的效果。
框架结构图:
框架原理:
pushController时:
disappearingViewController即将消失时,若存在动画,则将系统的Bar隐藏,重新生成一个新的Bar;
appearingViewController即将出现时,隐藏系统的Bar,生成新的Bar添加到当前控制器上,等到ViewDidAppear时将新加的Bar删掉,显示系统的Bar
popController时:
disappearingViewController即将消失时,若存在动画,则将系统的Bar隐藏,重新生成一个新的Bar;
appearingViewController即将出现时,隐藏系统的Bar,若上一步生成的Bar还在控制器上的话,等到ViewDidAppear时将生成的Bar删除,显示系统Bar
源码解析:
KMSwizzle.m文件转换函数实现功能
// KMSwizzle.h
#import <objc/runtime.h>
void KMSwizzleMethod(Class originalCls, SEL originalSelector, Class swizzledCls, SEL swizzledSelector) {
Method originalMethod = class_getInstanceMethod(originalCls, originalSelector);
Method swizzledMethod = class_getInstanceMethod(swizzledCls, swizzledSelector);
// 若originalCls当前类即子类没有实现时,则调用父类看是否有实现
// 1.父类有实现时,class_addMethod返回YES
// 2.父类无实现时,class_addMethod也返回YES,将swizzledMethod实现添加给originalSelector;若子类无originalSelector,则从父类查找。
BOOL didAddMethod =
class_addMethod(originalCls,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
//将originalCls的swizzledSelector用originalMethod替换
class_replaceMethod(originalCls,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
//originalMethod有实现,直接转换
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
KMWeakObjectContainer.m文件保存Vc控制器对象
// KMWeakObjectContainer
#import <objc/runtime.h>
@interface KMWeakObjectContainer : NSObject
@property (nonatomic, weak) id object; //用弱引用存放控制器对象,防止对象不被释放
@end
@implementation KMWeakObjectContainer
void km_objc_setAssociatedWeakObject(id container, void *key, id