DYLeftSlipManager
一行代碼實現(xiàn)側(cè)滑。完全解耦,兩個界面之間不需要有任何耦合。基于控制器自定義轉(zhuǎn)場。
Github:https://github.com/maybeisyi/DYLeftSlipManager
先上圖:
使用:
導(dǎo)入#import "DYLeftSlipManager.h"
// 注意這個控制器是右滑視圖控制器,由于完全解耦,所以在DYLeftSlipManager內(nèi)部是對該控制器強引用防止銷毀。
LeftTableViewController *leftVC = [LeftTableViewController new];
[[DYLeftSlipManager sharedManager] setLeftViewController:leftVC coverViewController:self];
// 這個self是覆蓋在右滑視圖上層的控制器,一般應(yīng)用中就是UITabbarController
嗯哼。是完全解耦的,你可以在任意地方調(diào)用這兩句代碼即可。
具體實現(xiàn)請看代碼(基于控制器轉(zhuǎn)場,并非 視圖+手勢 )。
相對于網(wǎng)上其他DEMO來說,本例是利用了控制器轉(zhuǎn)場實現(xiàn)的,其他DEMO基本都是View上加側(cè)滑View,這樣的話兩個界面之間耦合度太高,兩個View都歸一個C管,不能忍~~~本例就是兩個控制器,各管各的業(yè)務(wù)。
本例的簡析將在后續(xù)更新到簡書,目前簡析可在本人博客查看:daiyi.pro
——————————————我是分割線————————————————
標題是簡析,不是解析
所以我只談思路,不談詳細實現(xiàn)
DYLeftSlipManager是一個側(cè)滑菜單組件,它與別的側(cè)滑菜單不同的是,它將“側(cè)面菜單”以及“主頁面”之間完全解耦合。
GitHub地址:https://github.com/maybeisyi/DYLeftSlipManager
之前在各大論壇上看到的側(cè)滑菜單,各種仿QQ側(cè)滑菜單,仿XX側(cè)滑等等,均是在同一個ViewController(以下用VC代替)中,添加一個側(cè)面的視圖,然后通過手勢balabala的。能用嗎?當然能用,只要你不嫌你的VC夠臃腫。
側(cè)滑菜單頁面的內(nèi)容往往和主頁面的內(nèi)容關(guān)聯(lián)度不大(部分應(yīng)用中也有見到是有關(guān)聯(lián)的),一般來說都是可以獨立為一塊業(yè)務(wù)的(有關(guān)聯(lián)的基本也能抽象為一塊獨立業(yè)務(wù))。在這種場景下,你認為兩個業(yè)務(wù)同寫在一個VC里真的好嗎?
所以就有了這個輪子。
輪子思路
1. 如何抽象出這部分的業(yè)務(wù)?
業(yè)務(wù)的抽象還是需要靠類(甚至于模塊)來進行劃分。
2. 如何分離出這部分頁面?
頁面的分離,要么是自定義view,要么是另開一個VC。
自定義view可以實現(xiàn)頁面的分離,但是業(yè)務(wù)邏輯很難全都塞入view中進行管理,因為業(yè)務(wù)一般是VC或者單獨的業(yè)務(wù)類來進行管理。所以另開一個VC是目前較佳的選擇。
3. 如何在當前側(cè)滑的場景下另開一個VC?
首先不要將ViewController和view在腦海中混在一起,不要將VC當做view。VC是一個抽象的內(nèi)容,只是一堆代碼,你是看不見VC的,App上你看見的才是真真切切的view,只不過VC通常作為一個“完整頁面(一個手機屏幕大?。钡摹叭萜鳌贝嬖诙?。所謂“容器”,你理解成view是VC的一個屬性即可。
為了幫助你理解VC和view的關(guān)系,這里我舉個簡單的小例子:
這里我自定義一個繼承自NSObject的類:MyDog(用這個名字是為了有別于VC,這就是一條啊,沒錯!)
@interface MyDog : NSObject
@property (nonatomic, strong) UIView *view;
@end
@implementation MyDog
- (instancetype)init {
if ((self = [super init])) {
[self loadView];
}
return self;
}
- (void)loadView {
self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self viewDidLoad];
}
- (void)viewDidLoad {
// balabala
[self viewWillAppear];
}
- (void)viewWillAppear {
// balabala
[self viewDidAppear];
}
- (void)viewDidAppear {
// balabala
}
@end
這里的狗,含有一個view的屬性,還自定義了一些和VC“很像”的方法。
到這里應(yīng)該沒問題。
然后我們在默認的ViewController.m中,addSubview,把狗的view顯示出來:
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
MyDog *dog = [[MyDog alloc] init];
dog.view.frame = CGRectMake(100, 100, 100, 100);
[self.view addSubview:dog.view];
}
@end
沒問題吧,狗的view確實顯示出來了吧?那么,狗有個view,新建一個VC也有個view,我們是不是可以把dog換成VC呢?
- (void)viewDidLoad {
[super viewDidLoad];
UIViewController *VC = [[UIViewController alloc] init];
VC.view.frame = CGRectMake(100, 100, 100, 100);
VC.view.backgroundColor = [UIColor redColor];
[self.view addSubview:VC.view];
}
OK吧?現(xiàn)在你想清楚VC和view的關(guān)系了吧?
你沒想清楚MyDog和VC的關(guān)系?這么說把,Dog無法知道view在系統(tǒng)中何時willAppear、DidAppear等節(jié)點,所以無法精確的管理view的生命周期,但是VC可以,因為VC是蘋果提供的類,它的名字是“UIViewController”,也就是“view的控制器、管理器”,所以VC能管理view的生命周期,所以我們在VC里寫業(yè)務(wù)會更方便開發(fā)!
說了那么多,我就想說明一個觀點:
在一個VC里(主頁面),要另開一個VC(側(cè)滑菜單頁面),那就創(chuàng)建一個嘛,然后把側(cè)滑頁面的view
addSubview
到主頁面里不就完事了?
好了,業(yè)務(wù)與頁面都被抽象到另一個VC了(當然了你要自定義一個側(cè)滑菜單VC)。那么主頁面的VC和側(cè)滑菜單頁面的VC已經(jīng)邏輯分離,耦合松散了。只不過,主頁面此時還必須知道有“側(cè)滑頁面”這個VC的存在。
4. 進一步解耦合
在第3點中,我們已經(jīng)初步解耦合了,但是是不是有更優(yōu)雅的方式?
回想NavigationController,這個控制器存在的意義是什么?它可以將兩個VC進一步解耦合。
這個進一步解耦合是如何體現(xiàn)的呢?回想第3點,我們已經(jīng)做到了將兩塊業(yè)務(wù)分散到了兩個VC中,但是,view還是完全耦合在一起的,因為主頁面的view和側(cè)滑菜單頁面的view是通過addSubview
的方式進行關(guān)聯(lián)的。而NaviagtionController就是進一步將view解耦,通過NavigationController.view。
每個導(dǎo)航欄都有自己的view,上面只有一個NavigationBar視圖,下方是空視圖,第一個VC的view是addSubview
到導(dǎo)航欄的view上面的。然后我們push了第二個VC,那么第二個VC的view此時就不是直接addSubview
到第一個VC的view上去的,而是add到NavigationController.view上去的,然后伴隨推入的動畫將第二個VC的view進行顯示。此時第一個VC的view和第二個VC的view,不在是“父子”關(guān)系,而是“兄弟”關(guān)系了。
能理解這層解耦合關(guān)系吧?那么我們來說說我們的側(cè)滑菜單如何解耦合。
5. 側(cè)滑菜單如何解耦合—控制器轉(zhuǎn)場
這里不細說控制器轉(zhuǎn)場如何實現(xiàn),想學(xué)習(xí)的google一堆。這里想說的是轉(zhuǎn)場究竟是個什么東西。
控制器轉(zhuǎn)場就是通過一系列動畫,操作兩個VC的view進行切換顯示。切換顯示的時候,會有兩個VC的父view:containerView,然后兩個VC的view在上面add、remove,再加點動畫,就可以了。
無論是push還是present,都是轉(zhuǎn)場,就是操作view的addSubview
或者removeFromSuperview
。
一是給兩個VC解耦,二是做動畫,用戶體驗更友好。
控制器轉(zhuǎn)場的本質(zhì)就是view做動畫,操作view,和你的VC沒有太大關(guān)系
明白這個道理后,熟練使用各種動畫技能的你就可以在轉(zhuǎn)場中行云流水了。
等等,側(cè)滑可是兩個界面同時顯示?。∧阏f你都能控制兩個view了,你難道不能控制view的frame,不能控制view的大小,不能控制兩個view怎么疊加怎么擺放?不要被VC傳統(tǒng)的用法束縛,在這里,view才是你的主角。
輕總結(jié)
新手往往被蘋果指定的用法所束縛(如VC和view的關(guān)系),那是因為沒有清楚理解蘋果提供的“用法”的本質(zhì)。當然,蘋果的用法已經(jīng)足夠優(yōu)秀,你不必考慮部分細節(jié)也能進行使用,但是,理解“用法”的本質(zhì),才能讓你走的更遠。