一代赁、 MMDrawerController是一個輕量級的側(cè)邊欄抽屜控件,其支持左側(cè)抽屜和右側(cè)抽屜踊兜,可以很好的支持導(dǎo)航控制器竿滨,并且支持開發(fā)者對手勢和動畫進(jìn)行自定義
二、MMDrawerController的使用及相關(guān)設(shè)置 MMDrawerController的使用十分簡單,只需將中心視圖控制器和左邊欄視圖控制器傳入初始化方法即可完成MMDrawerController的創(chuàng)建于游。示例代碼如下:
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];
//創(chuàng)建控件
MMDrawerController * rootController = [[MMDrawerController alloc]initWithCenterViewController:centerViewController leftDrawerViewController:leftViewController rightDrawerViewController:rightViewController];
MMDrawerController中還提供了兩個方法供開發(fā)者創(chuàng)建單側(cè)邊欄毁葱,如下:
//只創(chuàng)建帶左側(cè)邊欄的視圖控制器
-(id)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController;
//只創(chuàng)建帶右側(cè)邊欄的視圖控制器
-(id)initWithCenterViewController:(UIViewController *)centerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController;
//MMDrawerController中也提供了許多屬性和方法供開發(fā)者進(jìn)行自定義的設(shè)置,其中可用屬性解析如下:
//設(shè)置左側(cè)邊欄的最大寬度 默認(rèn)280
@property (nonatomic, assign) CGFloat maximumLeftDrawerWidth;//設(shè)置右側(cè)邊欄的最大寬度 默認(rèn)280
@property (nonatomic, assign) CGFloat maximumRightDrawerWidth;
//這個是一個只讀屬性贰剥,用于獲取可見的左側(cè)邊欄寬度
@property (nonatomic, assign, readonly) CGFloat visibleLeftDrawerWidth;
//這個是一個只讀屬性倾剿,用于獲取可見的右側(cè)邊欄寬度
@property (nonatomic, assign, readonly) CGFloat visibleRightDrawerWidth;
//動畫速度,這個參數(shù)的意義是每秒移動多少單位 默認(rèn)為800/s
@property (nonatomic, assign) CGFloat animationVelocity;
//設(shè)置是否允許回彈效果蚌成,如果設(shè)置為YES前痘,當(dāng)使用手勢進(jìn)行側(cè)邊欄的開啟時會出現(xiàn)回彈效果
@property (nonatomic, assign) BOOL shouldStretchDrawer;
//獲取當(dāng)前開啟的側(cè)邊欄類型,MMDrawerSide枚舉如下:
/*typedef NS_ENUM(NSInteger,MMDrawerSide{
MMDrawerSideNone = 0,//無側(cè)邊欄
MMDrawerSideLeft,//左側(cè)邊欄
MMDrawerSideRight, //右側(cè)邊欄
};
*/@property (nonatomic, assign, readonly) MMDrawerSide openSide;
//開啟側(cè)邊欄的手勢模式 MMOpenDrawerGestureMode枚舉意義如下
/*typedef NS_OPTIONS(NSInteger, MMOpenDrawerGestureMode){
//沒有手勢 此模式為默認(rèn)模式
MMOpenDrawerGestureModeNone = 0,
//在導(dǎo)航欄上拖動時可以打開側(cè)邊欄
MMOpenDrawerGestureModePanningNavigationBar = 1 << 1,
//在中心視圖控制器的視圖上拖動時可以打開側(cè)邊欄
MMOpenDrawerGestureModePanningCenterView = 1 << 2,
//在中心視圖控制器的視圖邊緣20個單位內(nèi)拖動時可以打開側(cè)邊欄
MMOpenDrawerGestureModeBezelPanningCenterView = 1 << 3,
//自定義手勢 需配合自定義手勢的方法使用
MMOpenDrawerGestureModeCustom = 1 << 4,
//所有模式兼容
MMOpenDrawerGestureModeAll= MMOpenDrawerGestureModePanningNavigationBar |MMOpenDrawerGestureModePanningCenterView |MMOpenDrawerGestureModeBezelPanningCenterView |MMOpenDrawerGestureModeCustom,
};*/
@property (nonatomic, assign) MMOpenDrawerGestureMode openDrawerGestureModeMask;
//關(guān)閉側(cè)邊欄的手勢模式 MMCloseDrawerGestureMode枚舉的意義如下
/*typedef NS_OPTIONS(NSInteger, MMCloseDrawerGestureMode) {
//沒有關(guān)閉手勢
MMCloseDrawerGestureModeNone= 0,
//在導(dǎo)航欄上拖動時可以關(guān)閉側(cè)邊欄
MMCloseDrawerGestureModePanningNavigationBar= 1 << 1,
//在中心視圖控制器上推動時可以關(guān)閉側(cè)邊欄
MMCloseDrawerGestureModePanningCenterView= 1 << 2,
//在中心視圖控制器邊緣20單位內(nèi)拖動是可以關(guān)閉側(cè)邊欄
MMCloseDrawerGestureModeBezelPanningCenterView= 1 << 3,
//點(diǎn)擊導(dǎo)航欄時可以關(guān)閉側(cè)邊欄
MMCloseDrawerGestureModeTapNavigationBar = 1 << 4,
//點(diǎn)擊中心視圖控制器視圖時可以關(guān)閉側(cè)邊欄
MMCloseDrawerGestureModeTapCenterView= 1 << 5,
//在側(cè)邊欄視圖上拖動時可以關(guān)閉側(cè)邊欄
MMCloseDrawerGestureModePanningDrawerView= 1 << 6,
//自定義關(guān)閉手勢担忧,需要和自定義手勢的方法結(jié)合使用
MMCloseDrawerGestureModeCustom= 1 << 7,
//所有模式兼容
MMCloseDrawerGestureModeAll = MMCloseDrawerGestureModePanningNavigationBar|MMCloseDrawerGestureModePanningCenterView|MMCloseDrawerGestureModeBezelPanningCenterView|MMCloseDrawerGestureModeTapNavigationBar |MMCloseDrawerGestureModeTapCenterView|MMCloseDrawerGestureModePanningDrawerView|MMCloseDrawerGestureModeCustom,
};*/
@property (nonatomic, assign) MMCloseDrawerGestureMode closeDrawerGestureModeMask;
//設(shè)置側(cè)邊欄顯示時的中心視圖控制器的用戶交互規(guī)則 MMDrawerOpenCenterInteractionMode枚舉意義如下
/*typedef NS_ENUM(NSInteger, MMDrawerOpenCenterInteractionMode) {
//中心視圖控制器不能進(jìn)行用戶交互 默認(rèn)為此枚舉
MMDrawerOpenCenterInteractionModeNone,
//中心視圖控制器完全可以進(jìn)行用戶交互
MMDrawerOpenCenterInteractionModeFull,
//中心視圖控制器只有導(dǎo)航可以進(jìn)行用戶交互
MMDrawerOpenCenterInteractionModeNavigationBarOnly,
};*/
@property (nonatomic, assign) MMDrawerOpenCenterInteractionMode centerHiddenInteractionMode;
//設(shè)置是否顯示陰影效果
@property (nonatomic, assign) BOOL showsShadow;
//設(shè)置是否顯示狀態(tài)欄的自定義視圖 只有在iOS7之后可用
@property (nonatomic, assign) BOOL showsStatusBarBackgroundView;
//設(shè)置狀態(tài)欄視圖顏色 只有在iOS7之后可用
@property (nonatomic, strong) UIColor * statusBarViewBackgroundColor;
//相關(guān)方法解析如下:
//切換側(cè)邊欄的狀態(tài)芹缔,drawerSide參數(shù)為要切換的側(cè)邊欄,animated設(shè)置是否有動畫效果瓶盛,completion會在切換完成后執(zhí)行
//注意:如果在切換一個關(guān)著的側(cè)邊欄時最欠,如果另一個側(cè)邊欄正在開啟狀態(tài),則此方法不會有任何效果
-(void)toggleDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated completion:(void(^)(BOOL finished))completion;
//關(guān)閉側(cè)邊欄
-(void)closeDrawerAnimated:(BOOL)animated completion:(void(^)(BOOL finished))completion;
//開啟側(cè)邊欄-(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;
//設(shè)置左側(cè)邊欄最大寬度
-(void)setMaximumLeftDrawerWidth:(CGFloat)width animated:(BOOL)animated completion:(void(^)(BOOL finished))completion;
//設(shè)置右側(cè)邊欄最大寬度
-(void)setMaximumRightDrawerWidth:(CGFloat)width animated:(BOOL)animated completion:(void(^)(BOOL finished))completion;
//進(jìn)行側(cè)邊欄的預(yù)覽操作 默認(rèn)預(yù)覽距離為40個單位
-(void)bouncePreviewForDrawerSide:(MMDrawerSide)drawerSide completion:(void(^)(BOOL finished))completion;
//進(jìn)行側(cè)邊欄的預(yù)覽操作 可以設(shè)置預(yù)覽距離
-(void)bouncePreviewForDrawerSide:(MMDrawerSide)drawerSide distance:(CGFloat)distance completion:(void(^)(BOOL finished))completion;
//這個方法用于進(jìn)行視圖側(cè)邊欄視圖出現(xiàn)動畫的自定義
-(void)setDrawerVisualStateBlock:(void(^)(MMDrawerController * drawerController, MMDrawerSide drawerSide, CGFloat percentVisible))drawerVisualStateBlock;
//這個方法用于設(shè)置當(dāng)一個手勢觸發(fā)完成后的回調(diào)
-(void)setGestureCompletionBlock:(void(^)(MMDrawerController * drawerController, UIGestureRecognizer * gesture))gestureCompletionBlock;
//這個方法用于定義自定義的手勢操作 要將開啟側(cè)邊欄與關(guān)閉側(cè)邊欄的模式設(shè)置為MMOpenDrawerGestureModeCustom和MMCloseDrawerGestureModeCustom才有效
-(void)setGestureShouldRecognizeTouchBlock:(BOOL(^)(MMDrawerController * drawerController, UIGestureRecognizer * gesture, UITouch * touch))gestureShouldRecognizeTouchBlock;
//對于自定義過渡動畫的方法:
-(void)setDrawerVisualStateBlock:(void(^)(MMDrawerController * drawerController, MMDrawerSide drawerSide, CGFloat percentVisible))drawerVisualStateBlock;
//回調(diào)block中會傳遞進(jìn)來側(cè)邊欄顯示完成的百分比惩猫,并且在側(cè)邊欄出現(xiàn)過程中芝硬,這個回調(diào)block會被不停刷新調(diào)用,開發(fā)者可以直接在其中對要過渡的屬性進(jìn)行設(shè)置轧房,例如透明度的漸變動畫吵取,示例如下:
//進(jìn)行自定義動畫
[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];
}];
三、關(guān)于MMDrawerController的子類 開發(fā)者如果有特殊的需求锯厢,也可以通過繼承MMDrawerController來實(shí)現(xiàn)自己的側(cè)邊欄控制器類皮官,MMDrawerController框架中提供了一個擴(kuò)展,在編寫MMDrawerController時实辑,開發(fā)者可以導(dǎo)入MMDrawerController+Subclass.h文件捺氢,這個文件中提供了許多控制器的監(jiān)聽方法供開發(fā)者重寫,解析如下:
//出現(xiàn)單擊手勢會回調(diào)的方法 如果要重寫 必須調(diào)用父類的此方法
-(void)tapGestureCallback:(UITapGestureRecognizer *)tapGesture __attribute((objc_requires_super));
//出現(xiàn)滑動手勢會回調(diào)的方法 如果要重寫 必須調(diào)用父類的此方法
-(void)panGestureCallback:(UIPanGestureRecognizer *)panGesture __attribute((objc_requires_super));
//決定是否響應(yīng)某個手勢
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch __attribute((objc_requires_super));
//準(zhǔn)備展示側(cè)邊欄時調(diào)用的方法
-(void)prepareToPresentDrawer:(MMDrawerSide)drawer animated:(BOOL)animated __attribute((objc_requires_super));
//關(guān)閉側(cè)邊欄時調(diào)用的方法-(void)closeDrawerAnimated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL))completion __attribute((objc_requires_super));
//打開側(cè)邊欄時調(diào)用的方法
-(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL))completion __attribute((objc_requires_super));
//設(shè)備旋轉(zhuǎn)方向時調(diào)用的方法
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration __attribute((objc_requires_super));
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration __attribute((objc_requires_super));
四剪撬、一些輔助類 MMDrawerController框架中還提供了一個MMDrawerBarButtonItem的輔助類摄乒,這個類可以創(chuàng)建三道杠的菜單按鈕。其中方法如下:
//初始化方法
-(id)initWithTarget:(id)target action:(SEL)action;
//獲取某個狀態(tài)下的按鈕顏色
-(UIColor *)menuButtonColorForState:(UIControlState)state __attribute__((deprecated("Use tintColor instead")));
//設(shè)置某個狀態(tài)的按鈕顏色
-(void)setMenuButtonColor:(UIColor *)color forState:(UIControlState)state __attribute__((deprecated("Use tintColor instead")));
// MMDrawerBarButtonItem繼承自UIBarButtonItem残黑,可以直接在導(dǎo)航欄上使用馍佑。
前面有提到,側(cè)邊欄的展現(xiàn)動畫開發(fā)者可以進(jìn)行自定義梨水,為了使開發(fā)者在使用MMDrawerController時更加方便拭荤,MMDrawerController框架中還提供了一個動畫輔助類MMDrawerVisualState,這個類中封裝好了許多動畫效果疫诽,開發(fā)者可以直接使用舅世,示例如下:
//使用提供的動畫模板
[rootController setDrawerVisualStateBlock:[MMDrawerVisualState slideAndScaleVisualStateBlock]];
//MMDrawerVisualState中所提供的動畫模板列舉如下:
//從后向前漸現(xiàn)
+(MMDrawerControllerDrawerVisualStateBlock)slideAndScaleVisualStateBlock;
//滑動漸現(xiàn)
+(MMDrawerControllerDrawerVisualStateBlock)slideVisualStateBlock;
//立方動畫
+(MMDrawerControllerDrawerVisualStateBlock)swingingDoorVisualStateBlock;
//視差動畫
+(MMDrawerControllerDrawerVisualStateBlock)parallaxVisualStateBlockWithParallaxFactor:(CGFloat)parallaxFactor;
五旦委、MMDrawerController無法完成的需求 為了確保MMDrawerController庫的輕量級,其作者在設(shè)計(jì)時也做了功能上的取舍權(quán)衡雏亚,MMDrawerController無法完成以下需求:
1.上邊欄與下邊欄缨硝。
2.同時展示左邊欄與又邊欄。
3.無法設(shè)置顯示一個最小的抽屜寬度罢低。
4.不能支持UITabBarController容器查辩。
5.不能在中心視圖控制器之上呈現(xiàn)側(cè)邊欄視圖。