方案1 宿主工程
宿主工程
//刚开始做法
TGTabBarController *rootVC = [TGTabBarController tabBarControllerWithAddChildVCsBlock:^(TGTabBarController *tabBarC) {
[tabBarC addChildVC:[TestVC new] normalImageName:@"tabbar_find_n" selectedImageName:@"tabbar_find_h" isRequiredNavController:YES];
[tabBarC addChildVC:[UIViewController new] normalImageName:@"tabbar_sound_n" selectedImageName:@"tabbar_sound_h" isRequiredNavController:YES];
[tabBarC addChildVC:[UIViewController new] normalImageName:@"tabbar_download_n" selectedImageName:@"tabbar_download_h" isRequiredNavController:YES];
[tabBarC addChildVC:[UIViewController new] normalImageName:@"tabbar_me_n" selectedImageName:@"tabbar_me_h" isRequiredNavController:YES];
}];
TGTabBar *tabbar = (TGTabBar *)rootVC.tabBar;
tabbar.middleClickBlock = ^(BOOL isPlaying) {
if (isPlaying) {
NSLog(@"播放");
}else {
NSLog(@"暂停");
}
};
//暴露API
[MainModuleAPI addChildVC:[TestVC new] normalImageName:@"tabbar_find_n" selectedImageName:@"tabbar_find_h" isRequiredNavController:YES];
[MainModuleAPI addChildVC:[TestVC new] normalImageName:@"tabbar_sound_n" selectedImageName:@"tabbar_sound_h" isRequiredNavController:YES];
[MainModuleAPI addChildVC:[UIViewController new] normalImageName:@"tabbar_download_n" selectedImageName:@"tabbar_download_h" isRequiredNavController:YES];
[MainModuleAPI addChildVC:[TestVC new] normalImageName:@"tabbar_me_n" selectedImageName:@"tabbar_me_h" isRequiredNavController:YES];
[MainModuleAPI setTabbarMiddleBtnClick:^(BOOL isPlaying) {
if (isPlaying) {
NSLog(@"当前正在播放");
}else {
NSLog(@"当前正在暂停");
}
}];
@interface MainModuleAPI : NSObject
/**
获取根控制器
@return rootTabBarCcontroller
*/
+ (UITabBarController *)rootTabBarCcontroller;
/**
添加子控制器
@param vc 子控制器
@param normalImageName 普通状态下图片
@param selectedImageName 选中图片
@param isRequired 是否需要包装导航控制器
*/
+ (void)addChildVC: (UIViewController *)vc normalImageName: (NSString *)normalImageName selectedImageName:(NSString *)selectedImageName isRequiredNavController: (BOOL)isRequired;
/**
设置tabbar中间控件的点击代码块
@param middleClickBlock 点击代码块
*/
+ (void)setTabbarMiddleBtnClick: (void(^)(BOOL isPlaying))middleClickBlock;
/**
* 设置全局的导航栏背景图片
*
* @param globalImg 全局导航栏背景图片
*/
+ (void)setNavBarGlobalBackGroundImage: (UIImage *)globalImg;
/**
* 设置全局导航栏标题颜色, 和文字大小
*
* @param globalTextColor 全局导航栏标题颜色
* @param fontSize 全局导航栏文字大小
*/
+ (void)setNavBarGlobalTextColor: (UIColor *)globalTextColor andFontSize: (CGFloat)fontSize;
/**
快速获取中间按钮
@return 中间按钮, 通过通知 playState , playImage 控制 播放和播放图片
*/
//+ (UIView *)middleView;
@end
@implementation MainModuleAPI
+ (XMGTabBarController *)rootTabBarCcontroller {
return [XMGTabBarController shareInstance];
}
+ (void)addChildVC:(UIViewController *)vc normalImageName:(NSString *)normalImageName selectedImageName:(NSString *)selectedImageName isRequiredNavController:(BOOL)isRequired {
[[XMGTabBarController shareInstance] addChildVC:vc normalImageName:normalImageName selectedImageName:selectedImageName isRequiredNavController:isRequired];
}
+ (void)setTabbarMiddleBtnClick: (void(^)(BOOL isPlaying))middleClickBlock {
XMGTabBar *tabbar = (XMGTabBar *)[XMGTabBarController shareInstance].tabBar;
tabbar.middleClickBlock = middleClickBlock;
}
/**
* 设置全局的导航栏背景图片
*
* @param globalImg 全局导航栏背景图片
*/
+ (void)setNavBarGlobalBackGroundImage: (UIImage *)globalImg {
[XMGNavBar setGlobalBackGroundImage:globalImg];
}
/**
* 设置全局导航栏标题颜色, 和文字大小
*
* @param globalTextColor 全局导航栏标题颜色
* @param fontSize 全局导航栏文字大小
*/
+ (void)setNavBarGlobalTextColor: (UIColor *)globalTextColor andFontSize: (CGFloat)fontSize {
[XMGNavBar setGlobalTextColor:globalTextColor andFontSize:fontSize];
}
+ (UIView *)middleView {
return [XMGMiddleView middleView];
}
方案2 MGJRouter
@implementation MainModuleRouter
+ (void)load {
// [MGJRouter registerURLPattern:"xmg://geRootVC" toHandler:{
// NSLog(@"无返回值");
// }];
[MGJRouter registerURLPattern:@"xmg://getRootVC" toObjectHandler:^id(NSDictionary *routerParameters) {
return [MainModuleAPI rootTabBarCcontroller];
}];
[MGJRouter registerURLPattern:@"xmg://addChildVC" toHandler:^(NSDictionary *routerParameters) {
//MGJRouterParameterCompletetion 完成block、MGJRouterParameterUrl、MGJRouterParameterUserInfo
NSLog(@"%@", routerParameters);
NSDictionary *params = routerParameters[MGJRouterParameterUserInfo];
UIViewController *vc = params[@"vc"];
NSString *nImg = params[@"nImg"];
NSString *sImg = params[@"sImg"];
BOOL isR = [params[@"isR"] boolValue];
[MainModuleAPI addChildVC:vc normalImageName:nImg selectedImageName:sImg isRequiredNavController:isR];
void(^block)(id result) = routerParameters[MGJRouterParameterCompletion];
if (block != nil) {
block(@"xxx");
}
}];
[MainModuleAPI setTabbarMiddleBtnClick:^(BOOL isPlaying) {
[MGJRouter openURL:@"xmg://playAudio" withUserInfo:@{
@"isPlaying": @(isPlaying)
} completion:nil];
}];
}
@end
@implementation XMGAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//返回控制器
UIViewController *rootVC = [MGJRouter objectForURL:@"xmg://getRootVC"];
//没有返回值
[MGJRouter openURL:@"xmg://addChildVC" withUserInfo:@{
@"vc": [TestVC new],
@"nImg": @"tabbar_find_n",
@"sImg": @"tabbar_find_h",
@"isR": @(YES)
} completion:^(id result) {
NSLog(@"%@", result);
}];
[MGJRouter openURL:@"xmg://addChildVC" withUserInfo:@{
@"vc": [TestVC new],
@"nImg": @"tabbar_sound_n",
@"sImg": @"tabbar_sound_h",
@"isR": @(YES)
} completion:^(id result) {
NSLog(@"执行结果返回%@", result);
}];
[MGJRouter registerURLPattern:@"xmg://playAudio" toHandler:^(NSDictionary *routerParameters) {
NSLog(@"%@", routerParameters);
NSDictionary *param = routerParameters[MGJRouterParameterUserInfo];
BOOL isPlaying = [param[@"isPlaying"] boolValue];
if (isPlaying) {
NSLog(@"执行播放动作");
}else {
NSLog(@"执行暂停动作");
}
}];
self.window.rootViewController = rootVC;
[self.window makeKeyAndVisible];
return YES;
}
@end
实现方式:维护一张 url -> block 表
url:TG://Player
block : vc
缺点:
- 每个组件都依赖MGJRouter
- url多不易维护,需要硬解码
image.png
方案3 target-action
@interface XMGMediatorManager : NSObject
// 本地组件调用入口
+ (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(id)params isRequiredReturnValue: (BOOL)isRequiredReturnValue;
@end
@implementation XMGMediatorManager
// 本地组件调用入口
+ (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(id)params isRequiredReturnValue: (BOOL)isRequiredReturnValue {
// XMGMainModelTarget://log
// 1. 获取目标
Class targetCls = NSClassFromString(targetName);
if (targetCls == nil) {
NSLog(@"目标不存在");
return nil;
}
// 2. 获取行为
SEL sel = NSSelectorFromString(actionName);
if (sel == nil) {
NSLog(@"行为不存在");
return nil;
}
//NSObject *obj = [[targetCls alloc] init];
if (![targetCls respondsToSelector:sel]) {
NSLog(@"目标不存在该方法");
return nil;
}
if (isRequiredReturnValue) {
SuppressPerformSelectorLeakWarning(return [targetCls performSelector:sel withObject:params]);
}else {
SuppressPerformSelectorLeakWarning([targetCls performSelector:sel withObject:params]);
}
return nil;
}
@end
@interface XMGMediatorManager (XMGMain)
+ (UIViewController *)rootTabbarController;
+ (void)addChildVC: (UIViewController *)vc normalImageName: (NSString *)normalImageName selectedImageName:(NSString *)selectedImageName isRequiredNavController: (BOOL)isRequired;
+ (void)setTabbarMiddleBtnClick: (void(^)(BOOL isPlaying))middleClickBlock;
@end
@implementation XMGMediatorManager (XMGMain)
+ (UIViewController *)rootTabbarController {
UIViewController *vc = [self performTarget:@"MainModuleAPI" action:@"rootTabBarCcontroller" params:nil isRequiredReturnValue:YES];
// if (vc == nil) {
// return [UIViewController 404Page];
// }
return vc;
}
+ (void)addChildVC: (UIViewController *)vc normalImageName: (NSString *)normalImageName selectedImageName:(NSString *)selectedImageName isRequiredNavController: (BOOL)isRequired {
NSArray *param = @[vc, normalImageName, selectedImageName, @(isRequired)];
[self performTarget:@"MainModuleAPI" action:@"addChildVC:" params:param isRequiredReturnValue:NO];
}
+ (void)setTabbarMiddleBtnClick: (void(^)(BOOL isPlaying))middleClickBlock {
[self performTarget:@"MainModuleAPI" action:@"setTabbarMiddleBtnClick:" params:middleClickBlock isRequiredReturnValue:NO];
}
image.png