在 iOS組件化方案調(diào)研 這篇中垛膝,對組件化的應(yīng)用場景和實(shí)現(xiàn)方式做了簡單的調(diào)研。最終在項目中采用的是 casa 的
CTMediator
這套方案丁稀。以下是CTMediator 的一個簡單的使用教程吼拥。
一、普通頁面跳轉(zhuǎn)用法
假設(shè)我們有個頁面叫 OneViewController
线衫,當(dāng)前頁面為 HomeViewController
凿可,普通情況下頁面的間的跳轉(zhuǎn)方式如下:
#import "HomeViewController.h"
#import "OneViewController.h"
@implementation HomeViewController
- (void)aButtonClick:(UIButton *)sender {
OneViewController *viewController = [[OneViewController alloc] init];
viewController.name = @"普通用法"; //傳遞必要參數(shù)
[self.navigationController pushViewController:viewController animated:YES];
}
@end
這樣做看上去沒什么問題,實(shí)際也沒什么問題授账。
但是枯跑,考慮以下情況:
- 如果
HomeViewController
里有 N 個這樣的 button 事件,每個點(diǎn)擊后的跳轉(zhuǎn)都是不同的頁面白热,那么則HomeViewController
里全肮,需要導(dǎo)入 N 個這樣的OneViewController.h
; - 如果
HomeViewController
是一個可以移植到其它項目的業(yè)務(wù)模塊,在拖出首頁HomeVC
相關(guān)的業(yè)務(wù)代碼時棘捣,難道還要把 'HomeViewController.m' 導(dǎo)入的 N 個其它XxxViewController.h
都一塊拖到新項目中么辜腺?
這點(diǎn)就是因?yàn)榇a的耦合導(dǎo)致了首頁 HomeVC
沒法方便的移植休建。
說這樣沒有問題,是因?yàn)槠胀ㄇ闆r下评疗,我們并沒有移植 HomeVC
到其它項目的需求测砂。
至于什么時候會有這樣的問題,以及百匆,這樣的問題如果解決砌些,在 iOS組件化方案調(diào)研 這篇中,已經(jīng)做過簡單的討論加匈,這篇主要是選取了我個人較偏向的 Target-Action
這套方案存璃,簡單講一下實(shí)現(xiàn)方式。
二雕拼、Target-Action 實(shí)現(xiàn)頁面跳轉(zhuǎn)
采用的是 CTMediator
這套方案
Demo地址
還是假設(shè)我們有個頁面叫 NewsViewController
, 當(dāng)前頁面為HomeViewController
那么纵东,我們按照CTMediator
設(shè)計的架構(gòu)來寫一遍這個流程
1.創(chuàng)建Target-Action
創(chuàng)建一個 Target_News
類,在這個文件里啥寇,我們主要生成 NewsViewController 實(shí)例并為其進(jìn)行一些必要的賦值偎球。例如:
// Target_News.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface Target_News : NSObject
- (UIViewController *)Action_NativeToNewsViewController:(NSDictionary *)params;
@end
這個類需要直接 #import "NewsViewController.h"
// Target_News.m
#import "Target_News.h"
#import "NewsViewController.h"
@implementation Target_News
- (UIViewController *)Action_NativeToNewsViewController:(NSDictionary *)params {
NewsViewController *newsVC = [[NewsViewController alloc] init];
if ([params valueForKey:@"newsID"]) {
newsVC.newsID = params[@"newsID"];
}
return newsVC;
}
@end
2.創(chuàng)建 CTMediator 的Category.
CTMediator+NewsActions.這個Category利用Runtime調(diào)用我們剛剛生成的Target_News。
由于利用了Runtime辑甜,導(dǎo)致我們完全不用#import剛剛生成的Target_News即可執(zhí)行里面的方法衰絮,所以這一步,兩個類是完全解耦的磷醋。也即是說猫牡,我們在完全解耦的情況下獲取到了我們需要的NewsViewController。例如:
// CTMediator+NewsActions.h
#import "CTMediator.h"
#import <UIKit/UIKit.h>
@interface CTMediator (NewsActions)
- (UIViewController *)yt_mediator_newsViewControllerWithParams:(NSDictionary *)dict;
@end
// CTMediator+NewsActions.m
#import "CTMediator+NewsActions.h"
NSString * const kCTMediatorTarget_News = @"News";
NSString * const kCTMediatorActionNativTo_NewsViewController = @"NativeToNewsViewController";
@implementation CTMediator (NewsActions)
- (UIViewController *)yt_mediator_newsViewControllerWithParams:(NSDictionary *)dict {
UIViewController *viewController = [self performTarget:kCTMediatorTarget_News
action:kCTMediatorActionNativTo_NewsViewController
params:dict];
if ([viewController isKindOfClass:[UIViewController class]]) {
return viewController;
} else {
NSLog(@"%@ 未能實(shí)例化頁面", NSStringFromSelector(_cmd));
return [[UIViewController alloc] init];
}
}
@end
3.最終使用
由于在Target中邓线,傳遞值得方式采用了去Model化得方式淌友,導(dǎo)致我們在整個過程中也沒有#import任何Model。所以褂痰,我們的每個類都與Model解耦。
// HomeViewController.m
#import "HomeViewController.h"
#import "CTMediator+NewsActions.h"
@implementation HomeViewController
- (void)bButtonClick:(UIButton *)sender {
UIViewController *viewController = [[CTMediator sharedInstance] yt_mediator_newsViewControllerWithParams:@{@"newsID":@"123456"}];
[self.navigationController pushViewController:viewController animated:YES];
}
@end
4.不足
這里其實(shí)唯一的問題就是症虑,Target_Action里不得不填入一些 Hard Code缩歪,就是對創(chuàng)建的VC的賦值語句。不過這也是為了達(dá)到最大限度的解耦和靈活度而做的權(quán)衡谍憔。
// 1. kCTMediatorTarget_News字符串 是 Target_xxx.h 中的 xxx 部分
NSString * const kCTMediatorTarget_News = @"News";
// 2. kCTMediatorActionNativTo_NewsViewController 是 Target_xxx.h 中 定義的 Action_xxxx 函數(shù)名的 xxx 部分
NSString * const kCTMediatorActionNativTo_NewsViewController = @"NativeToNewsViewController";
注:這篇寫的較早匪蝙。作者前段時間也親自寫了篇教程:在現(xiàn)有工程中實(shí)施基于CTMediator的組件化方案 比這篇詳盡,各位還是移步原 po 的教程吧……