iOS MMDrawerController源码解读(一)
??提前說好,本文絕對不是教你如何使用MMDrawerController這個第三方庫,因為那太多人寫了 ,也太簡單了。這篇文章主要帶你分析MMDrawerController是怎么實現抽屜效果,明白第三方庫的內部原理。例外,本人也封裝了一個FHSegmentControl的第三方庫,歡迎大家去看看啊。
1.MMDrawerController的實例化方法
??先明確幾個變量的意義。
// 中央控制器 @property (nonatomic, strong) UIViewController * centerViewController; // 左側控制器、右側控制器,統稱側邊控制器 @property (nonatomic, strong) UIViewController * leftDrawerViewController; @property (nonatomic, strong) UIViewController * rightDrawerViewController;??我分析第三方庫,都是從實例化方法開始的。那么多類,方法更多,必須有一個開始。從實例化方法開始,可以找出作者的思考方式,這里也就是怎么實現抽屜效果的。
// 1. -(instancetype)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController{NSParameterAssert(centerViewController);self = [super init];if(self){[self setCenterViewController:centerViewController];[self setLeftDrawerViewController:leftDrawerViewController];[self setRightDrawerViewController:rightDrawerViewController];}return self; } // 2. -(instancetype)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController{return [self initWithCenterViewController:centerViewController leftDrawerViewController:leftDrawerViewController rightDrawerViewController:nil]; } //3. -(instancetype)initWithCenterViewController:(UIViewController *)centerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController{return [self initWithCenterViewController:centerViewController leftDrawerViewController:nil rightDrawerViewController:rightDrawerViewController]; }??一共有3個實例方法,第2.3個實例方法,最后都得調用第1個實例方法,所以我們只要分析第1個實例方法就可以了。第一個實例方法調用了三個方法。
// 4[self setCenterViewController:centerViewController];// 5[self setLeftDrawerViewController:leftDrawerViewController];// 6[self setRightDrawerViewController:rightDrawerViewController];??我們先看第5、6個方法。
```
-(void)setRightDrawerViewController:(UIViewController *)rightDrawerViewController{
[self setDrawerViewController:rightDrawerViewController forSide:MMDrawerSideRight];
}
-(void)setLeftDrawerViewController:(UIViewController *)leftDrawerViewController{
[self setDrawerViewController:leftDrawerViewController forSide:MMDrawerSideLeft];
}
- (void)setDrawerViewController:(UIViewController *)viewController forSide:(MMDrawerSide)drawerSide;
// 1.添加中央控制器
-(void)setCenterViewController:(UIViewController *)centerViewController;
// 2.添加左右兩邊的控制器
- (void)setDrawerViewController:(UIViewController *)viewController forSide:(MMDrawerSide)drawerSide;
// 1.
-(void)setCenterViewController:(UIViewController )centerViewController{
[self setCenterViewController:centerViewController animated:NO];
}
//2.直接看這個方法就好了,因為第一個方法也是調用這個方法
-(void)setCenterViewController:(UIViewController )centerViewController animated:(BOOL)animated{
// 如果將要添加的中央控制器和原來的一樣,就不要再添加了
// self.centerViewController 已經添加的中央內容控制器。第一次實例化,為nil。
if ([self.centerViewController isEqual:centerViewController]) {
// 添加中央內容視圖,也就是:往self.childControllerContainerView上添加self.centerContainerView
if (_centerContainerView == nil) {
// self.childControllerContainerView 是一個添加在self.view 上面和self.view位置和大小一樣的UIView。
CGRect centerFrame = self.childControllerContainerView.bounds;
if(self.centerContainerView == nil){
// MMDrawerCenterContainerView 先當做UIView,后面在慢慢分析
self.centerContainerView = [[MMDrawerCenterContainerView alloc] initWithFrame:centerFrame];
[self.centerContainerView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
[self.centerContainerView setBackgroundColor:[UIColor clearColor]];
//開始時: self.openSide = MMDrawerSideNone;因為我們實例化的時候,并沒有展示左右邊兩邊的抽屜視圖
[self.centerContainerView setOpenSide:self.openSide];
//開始時: self.centerHiddenInteractionMode = MMDrawerOpenCenterInteractionModeNavigationBarOnly;設置響應模式
[self.centerContainerView setCenterInteractionMode:MMDrawerOpenCenterInteractionModeNone];
[self.childControllerContainerView addSubview:self.centerContainerView];
}
}
// 因為要添加新的中央控制器,如果舊的存在,就要刪除
UIViewController * oldCenterViewController = self.centerViewController;
if(oldCenterViewController){
[oldCenterViewController willMoveToParentViewController:nil];
if(animated == NO){
[oldCenterViewController beginAppearanceTransition:NO animated:NO];
}
[oldCenterViewController.view removeFromSuperview];
if(animated == NO){
[oldCenterViewController endAppearanceTransition];
}
[oldCenterViewController removeFromParentViewController];
}
// 添加新的中央控制器
_centerViewController = centerViewController;
[self addChildViewController:self.centerViewController];
[self.centerViewController.view setFrame:self.childControllerContainerView.bounds];
[self.centerContainerView addSubview:self.centerViewController.view];
// 把中央視圖放在子視圖容器最前面
[self.childControllerContainerView bringSubviewToFront:self.centerContainerView];
[self.centerViewController.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
// 設置陰影,以后講
[self updateShadowForCenterView];
}
  其實這里一共有四個View,這四個View的大小和位置都是一樣的。self 是MMDrawerController 的對象。它們的層級結構就是: self.view -> self.childControllerContainerView ->self.centerContainerView -> self.centerViewController.view。中央控制器的view在最上面,運行APP的時候,最先看到。###3.添加側邊控制器(void)setDrawerViewController:(UIViewController )viewController forSide:(MMDrawerSide)drawerSide{
// 如果你添加的是中央控制器,程序就會崩潰。因為這個方法只能添加左右兩邊的控制器。
NSParameterAssert(drawerSide != MMDrawerSideNone);
// 這個方法,可以獲得當前的左邊或右邊的控制器
UIViewController currentSideViewController = [self sideDrawerViewControllerForSide:drawerSide];
// 如果和原來的側邊視圖控制器相同,就不必添加了
if (currentSideViewController == viewController) {
return;
}
// 如果原來已經有了側邊視圖控制器,移除
if (currentSideViewController != nil) {
[currentSideViewController beginAppearanceTransition:NO animated:NO];
[currentSideViewController.view removeFromSuperview];
[currentSideViewController endAppearanceTransition];
[currentSideViewController willMoveToParentViewController:nil];
[currentSideViewController removeFromParentViewController];
}
// 添加新的側邊視圖控制器
// 左邊
UIViewAutoresizing autoResizingMask = 0;
if (drawerSide == MMDrawerSideLeft) {
_leftDrawerViewController = viewController;
autoResizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;}
// 右邊
else if(drawerSide == MMDrawerSideRight){
_rightDrawerViewController = viewController;
autoResizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
}
// viewController不為空,代表你想添加側邊控制器
if(viewController){
[self addChildViewController:viewController];
// 實例化的時候不走,直接看else里面的方法
if((self.openSide == drawerSide) &&
[self.childControllerContainerView.subviews containsObject:self.centerContainerView]){
[self.childControllerContainerView insertSubview:viewController.view belowSubview:self.centerContainerView];
[viewController beginAppearanceTransition:YES animated:NO];
[viewController endAppearanceTransition];
}
else{
// 添加新的側邊控制器
[self.childControllerContainerView addSubview:viewController.view];
[self.childControllerContainerView sendSubviewToBack:viewController.view];
[viewController.view setHidden:YES];
}
[viewController didMoveToParentViewController:self];
[viewController.view setAutoresizingMask:autoResizingMask];
//側邊欄的最大寬度默認280.
// H:代表self.view的高,W代表self.view的寬,w代表側邊欄的最大的寬度
// 左側視圖的frame: (0,0,w,H);右側視圖的frame: (W-w,0,w,H);
[viewController.view setFrame:viewController.mm_visibleDrawerFrame];
}
}
```
??這篇文章介紹了MMDrawerController的實例化方法和各個控制器與視圖的層級結構,下篇文章主要講側邊欄的切換動畫。如果喜歡就推薦一下吧!
轉載于:https://www.cnblogs.com/doujiangyoutiao/p/6409108.html
總結
以上是生活随笔為你收集整理的iOS MMDrawerController源码解读(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nodeMCU自动化控制实现空气质量管家
- 下一篇: JSONP简单入门介绍