不少應用程序都採用了側邊欄這樣的界面結構,MMDrawerController是一個輕量級的側邊欄抽屜控件,其支持左側抽屜和右側抽屜,能夠很好的支持導航控制器,而且支持開發者對手勢和動畫進行自定義。MMDrawerController的git地址以下:git
https://github.com/mutualmobile/MMDrawerController。github
MMDrawerController的使用十分簡單,只需將中心視圖控制器和左邊欄視圖控制器傳入初始化方法便可完成MMDrawerController的建立。示例代碼以下:框架
UIViewController * leftViewController = [[UIViewController alloc]init]; leftViewController.view.backgroundColor = [UIColor redColor]; UIViewController * rightViewController = [[UIViewController alloc]init]; rightViewController.view.backgroundColor = [UIColor greenColor]; ViewController * centerViewController = [[ViewController alloc]init]; centerViewController.view.backgroundColor = [UIColor blueColor]; //建立控件 MMDrawerController * rootController = [[MMDrawerController alloc]initWithCenterViewController:centerViewController leftDrawerViewController:leftViewController rightDrawerViewController:rightViewController];
MMDrawerController中還提供了兩個方法供開發者建立單側邊欄,以下:ide
//只建立帶左側邊欄的視圖控制器 -(id)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController; //只建立帶右側邊欄的視圖控制器 -(id)initWithCenterViewController:(UIViewController *)centerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController;
MMDrawerController中也提供了許多屬性和方法供開發者進行自定義的設置,其中可用屬性解析以下:動畫
//設置左側邊欄的最大寬度 默認280 @property (nonatomic, assign) CGFloat maximumLeftDrawerWidth; //設置右側邊欄的最大寬度 默認280 @property (nonatomic, assign) CGFloat maximumRightDrawerWidth; //這個是一個只讀屬性,用於獲取可見的左側邊欄寬度 @property (nonatomic, assign, readonly) CGFloat visibleLeftDrawerWidth; //這個是一個只讀屬性,用於獲取可見的右側邊欄寬度 @property (nonatomic, assign, readonly) CGFloat visibleRightDrawerWidth; //動畫速度,這個參數的意義是每秒移動多少單位 默認爲800/s @property (nonatomic, assign) CGFloat animationVelocity; //設置是否容許回彈效果,若是設置爲YES,當使用手勢進行側邊欄的開啓時會出現回彈效果 @property (nonatomic, assign) BOOL shouldStretchDrawer; //獲取當前開啓的側邊欄類型,MMDrawerSide枚舉以下: /* typedef NS_ENUM(NSInteger,MMDrawerSide){ MMDrawerSideNone = 0,//無側邊欄 MMDrawerSideLeft, //左側邊欄 MMDrawerSideRight, //右側邊欄 }; */ @property (nonatomic, assign, readonly) MMDrawerSide openSide; //開啓側邊欄的手勢模式 MMOpenDrawerGestureMode枚舉意義以下 /* typedef NS_OPTIONS(NSInteger, MMOpenDrawerGestureMode) { //沒有手勢 此模式爲默認模式 MMOpenDrawerGestureModeNone = 0, //在導航欄上拖動時能夠打開側邊欄 MMOpenDrawerGestureModePanningNavigationBar = 1 << 1, //在中心視圖控制器的視圖上拖動時能夠打開側邊欄 MMOpenDrawerGestureModePanningCenterView = 1 << 2, //在中心視圖控制器的視圖邊緣20個單位內拖動時能夠打開側邊欄 MMOpenDrawerGestureModeBezelPanningCenterView = 1 << 3, //自定義手勢 需配合自定義手勢的方法使用 MMOpenDrawerGestureModeCustom = 1 << 4, //全部模式兼容 MMOpenDrawerGestureModeAll = MMOpenDrawerGestureModePanningNavigationBar | MMOpenDrawerGestureModePanningCenterView | MMOpenDrawerGestureModeBezelPanningCenterView | MMOpenDrawerGestureModeCustom, }; */ @property (nonatomic, assign) MMOpenDrawerGestureMode openDrawerGestureModeMask; //關閉側邊欄的手勢模式 MMCloseDrawerGestureMode枚舉的意義以下 /* typedef NS_OPTIONS(NSInteger, MMCloseDrawerGestureMode) { //沒有關閉手勢 MMCloseDrawerGestureModeNone = 0, //在導航欄上拖動時能夠關閉側邊欄 MMCloseDrawerGestureModePanningNavigationBar = 1 << 1, //在中心視圖控制器上推進時能夠關閉側邊欄 MMCloseDrawerGestureModePanningCenterView = 1 << 2, //在中心視圖控制器邊緣20單位內拖動是能夠關閉側邊欄 MMCloseDrawerGestureModeBezelPanningCenterView = 1 << 3, //點擊導航欄時能夠關閉側邊欄 MMCloseDrawerGestureModeTapNavigationBar = 1 << 4, //點擊中心視圖控制器視圖時能夠關閉側邊欄 MMCloseDrawerGestureModeTapCenterView = 1 << 5, //在側邊欄視圖上拖動時能夠關閉側邊欄 MMCloseDrawerGestureModePanningDrawerView = 1 << 6, //自定義關閉手勢,須要和自定義手勢的方法結合使用 MMCloseDrawerGestureModeCustom = 1 << 7, //全部模式兼容 MMCloseDrawerGestureModeAll = MMCloseDrawerGestureModePanningNavigationBar | MMCloseDrawerGestureModePanningCenterView | MMCloseDrawerGestureModeBezelPanningCenterView | MMCloseDrawerGestureModeTapNavigationBar | MMCloseDrawerGestureModeTapCenterView | MMCloseDrawerGestureModePanningDrawerView | MMCloseDrawerGestureModeCustom, }; */ @property (nonatomic, assign) MMCloseDrawerGestureMode closeDrawerGestureModeMask; //設置側邊欄顯示時的中心視圖控制器的用戶交互規則 MMDrawerOpenCenterInteractionMode枚舉意義以下 /* typedef NS_ENUM(NSInteger, MMDrawerOpenCenterInteractionMode) { //中心視圖控制器不能進行用戶交互 默認爲此枚舉 MMDrawerOpenCenterInteractionModeNone, //中心視圖控制器徹底能夠進行用戶交互 MMDrawerOpenCenterInteractionModeFull, //中心視圖控制器只有導航能夠進行用戶交互 MMDrawerOpenCenterInteractionModeNavigationBarOnly, }; */ @property (nonatomic, assign) MMDrawerOpenCenterInteractionMode centerHiddenInteractionMode; //設置是否顯示陰影效果 @property (nonatomic, assign) BOOL showsShadow; //設置是否顯示狀態欄的自定義視圖 只有在iOS7以後可用 @property (nonatomic, assign) BOOL showsStatusBarBackgroundView; //設置狀態欄視圖顏色 只有在iOS7以後可用 @property (nonatomic, strong) UIColor * statusBarViewBackgroundColor;
相關方法解析以下:ui
//切換側邊欄的狀態,drawerSide參數爲要切換的側邊欄,animated設置是否有動畫效果,completion會在切換完成後執行 //注意:若是在切換一個關着的側邊欄時,若是另外一個側邊欄正在開啓狀態,則此方法不會有任何效果 -(void)toggleDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated completion:(void(^)(BOOL finished))completion; //關閉側邊欄 -(void)closeDrawerAnimated:(BOOL)animated completion:(void(^)(BOOL finished))completion; //開啓側邊欄 -(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated completion:(void(^)(BOOL finished))completion; //更換中心視圖控制器 -(void)setCenterViewController:(UIViewController *)centerViewController withCloseAnimation:(BOOL)closeAnimated completion:(void(^)(BOOL finished))completion; -(void)setCenterViewController:(UIViewController *)newCenterViewController withFullCloseAnimation:(BOOL)fullCloseAnimated completion:(void(^)(BOOL finished))completion; //設置左側邊欄最大寬度 -(void)setMaximumLeftDrawerWidth:(CGFloat)width animated:(BOOL)animated completion:(void(^)(BOOL finished))completion; //設置右側邊欄最大寬度 -(void)setMaximumRightDrawerWidth:(CGFloat)width animated:(BOOL)animated completion:(void(^)(BOOL finished))completion; //進行側邊欄的預覽操做 默認預覽距離爲40個單位 -(void)bouncePreviewForDrawerSide:(MMDrawerSide)drawerSide completion:(void(^)(BOOL finished))completion; //進行側邊欄的預覽操做 能夠設置預覽距離 -(void)bouncePreviewForDrawerSide:(MMDrawerSide)drawerSide distance:(CGFloat)distance completion:(void(^)(BOOL finished))completion; //這個方法用於進行視圖側邊欄視圖出現動畫的自定義 -(void)setDrawerVisualStateBlock:(void(^)(MMDrawerController * drawerController, MMDrawerSide drawerSide, CGFloat percentVisible))drawerVisualStateBlock; //這個方法用於設置當一個手勢觸發完成後的回調 -(void)setGestureCompletionBlock:(void(^)(MMDrawerController * drawerController, UIGestureRecognizer * gesture))gestureCompletionBlock; //這個方法用於定義自定義的手勢操做 要將開啓側邊欄與關閉側邊欄的模式設置爲MMOpenDrawerGestureModeCustom和MMCloseDrawerGestureModeCustom纔有效 -(void)setGestureShouldRecognizeTouchBlock:(BOOL(^)(MMDrawerController * drawerController, UIGestureRecognizer * gesture, UITouch * touch))gestureShouldRecognizeTouchBlock;
對於自定義過渡動畫的方法:atom
-(void)setDrawerVisualStateBlock:(void(^)(MMDrawerController * drawerController, MMDrawerSide drawerSide, CGFloat percentVisible))drawerVisualStateBlock;spa
回調block中會傳遞進來側邊欄顯示完成的百分比,而且在側邊欄出現過程當中,這個回調block會被不停刷新調用,開發者能夠直接在其中對要過渡的屬性進行設置,例如透明度的漸變更畫,示例以下:設計
//進行自定義動畫 [rootController setDrawerVisualStateBlock:^(MMDrawerController *drawerController, MMDrawerSide drawerSide, CGFloat percentVisible) { UIViewController * sideDrawerViewController; if(drawerSide == MMDrawerSideLeft){ sideDrawerViewController = drawerController.leftDrawerViewController; } else if(drawerSide == MMDrawerSideRight){ sideDrawerViewController = drawerController.rightDrawerViewController; } [sideDrawerViewController.view setAlpha:percentVisible]; }];
開發者若是有特殊的需求,也能夠經過繼承MMDrawerController來實現本身的側邊欄控制器類,MMDrawerController框架中提供了一個擴展,在編寫MMDrawerController時,開發者能夠導入MMDrawerController+Subclass.h文件,這個文件中提供了許多控制器的監聽方法供開發者重寫,解析以下:code
//出現單擊手勢會回調的方法 若是要重寫 必須調用父類的此方法 -(void)tapGestureCallback:(UITapGestureRecognizer *)tapGesture __attribute((objc_requires_super)); //出現滑動手勢會回調的方法 若是要重寫 必須調用父類的此方法 -(void)panGestureCallback:(UIPanGestureRecognizer *)panGesture __attribute((objc_requires_super)); //決定是否響應某個手勢 -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch __attribute((objc_requires_super)); //準備展現側邊欄時調用的方法 -(void)prepareToPresentDrawer:(MMDrawerSide)drawer animated:(BOOL)animated __attribute((objc_requires_super)); //關閉側邊欄時調用的方法 -(void)closeDrawerAnimated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL))completion __attribute((objc_requires_super)); //打開側邊欄時調用的方法 -(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL))completion __attribute((objc_requires_super)); //設備旋轉方向時調用的方法 -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration __attribute((objc_requires_super)); -(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration __attribute((objc_requires_super));
MMDrawerController框架中還提供了一個MMDrawerBarButtonItem的輔助類,這個類能夠建立三道槓的菜單按鈕。其中方法以下:
//初始化方法 -(id)initWithTarget:(id)target action:(SEL)action; //獲取某個狀態下的按鈕顏色 -(UIColor *)menuButtonColorForState:(UIControlState)state __attribute__((deprecated("Use tintColor instead"))); //設置某個狀態的按鈕顏色 -(void)setMenuButtonColor:(UIColor *)color forState:(UIControlState)state __attribute__((deprecated("Use tintColor instead")));
MMDrawerBarButtonItem繼承自UIBarButtonItem,能夠直接在導航欄上使用。
前面有提到,側邊欄的展示動畫開發者能夠進行自定義,爲了使開發者在使用MMDrawerController時更加方便,MMDrawerController框架中還提供了一個動畫輔助類MMDrawerVisualState,這個類中封裝好了許多動畫效果,開發者能夠直接使用,示例以下:
//使用提供的動畫模板 [rootController setDrawerVisualStateBlock:[MMDrawerVisualState slideAndScaleVisualStateBlock]];
MMDrawerVisualState中所提供的動畫模板列舉以下:
//從後向前漸現 +(MMDrawerControllerDrawerVisualStateBlock)slideAndScaleVisualStateBlock; //滑動漸現 +(MMDrawerControllerDrawerVisualStateBlock)slideVisualStateBlock; //立方動畫 +(MMDrawerControllerDrawerVisualStateBlock)swingingDoorVisualStateBlock; //視差動畫 +(MMDrawerControllerDrawerVisualStateBlock)parallaxVisualStateBlockWithParallaxFactor:(CGFloat)parallaxFactor;
爲了確保MMDrawerController庫的輕量級,其做者在設計時也作了功能上的取捨權衡,MMDrawerController沒法完成如下需求:
1.上邊欄與下邊欄。
2.同時展現左邊欄與又邊欄。
3.沒法設置顯示一個最小的抽屜寬度。
4.不能支持UITabBarController容器。
5.不能在中心視圖控制器之上呈現側邊欄視圖。
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:203317592