日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS MMDrawerController源码解读(一)

發布時間:2025/3/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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;
??綜上所述,我們要明白MMDrawerController是怎樣創建的,只要明白下面的兩個方法就可以了,頓時感覺工作量少了很多有沒有。

// 1.添加中央控制器
-(void)setCenterViewController:(UIViewController *)centerViewController;
// 2.添加左右兩邊的控制器

  • (void)setDrawerViewController:(UIViewController *)viewController forSide:(MMDrawerSide)drawerSide;
###2.添加中央控制器

// 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]) {

return; }

// 添加中央內容視圖,也就是:往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];

if(animated == NO){// 實例化的時候,這個方法不走// self.view.window 是判斷是否添加到了手機屏幕上,也就是keyWindow上。if(self.view.window) {[self.centerViewController beginAppearanceTransition:YES animated:NO];[self.centerViewController endAppearanceTransition];}//告訴系統有一個視圖控制器從容器中添加或者移除[self.centerViewController didMoveToParentViewController:self]; }

}

  其實這里一共有四個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源码解读(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。