iOS好用的第三方侧边栏控件——MMDrawerController
一、引言
很多应用程序都采用了侧边栏这样的界面结构,MMDrawerController是一个轻量级的侧边栏抽屉控件,其支持左侧抽屉和右侧抽屉,可以很好的支持导航控制器,并且支持开发者对手势和动画进行自定义。MMDrawerController的git地址如下:
https://github.com/mutualmobile/MMDrawerController。
二、MMDrawerController的使用及相关设置
MMDrawerController的使用十分简单,只需将中心视图控制器和左边栏视图控制器传入初始化方法即可完成MMDrawerController的创建。示例代码如下:
1 2 3 4 5 6 7 8
| 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中还提供了两个方法供开发者创建单侧边栏,如下:
1 2 3 4
| -(id)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController;
-(id)initWithCenterViewController:(UIViewController *)centerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController;
|
MMDrawerController中也提供了许多属性和方法供开发者进行自定义的设置,其中可用属性解析如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| @property (nonatomic, assign) CGFloat maximumLeftDrawerWidth;
@property (nonatomic, assign) CGFloat maximumRightDrawerWidth;
@property (nonatomic, assign, readonly) CGFloat visibleLeftDrawerWidth;
@property (nonatomic, assign, readonly) CGFloat visibleRightDrawerWidth;
@property (nonatomic, assign) CGFloat animationVelocity;
@property (nonatomic, assign) BOOL shouldStretchDrawer;
@property (nonatomic, assign, readonly) MMDrawerSide openSide;
@property (nonatomic, assign) MMOpenDrawerGestureMode openDrawerGestureModeMask;
@property (nonatomic, assign) MMCloseDrawerGestureMode closeDrawerGestureModeMask;
@property (nonatomic, assign) MMDrawerOpenCenterInteractionMode centerHiddenInteractionMode;
@property (nonatomic, assign) BOOL showsShadow;
@property (nonatomic, assign) BOOL showsStatusBarBackgroundView;
@property (nonatomic, strong) UIColor * statusBarViewBackgroundColor;
|
相关方法解析如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
-(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;
-(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;
-(void)setGestureShouldRecognizeTouchBlock:(BOOL(^)(MMDrawerController * drawerController, UIGestureRecognizer * gesture, UITouch * touch))gestureShouldRecognizeTouchBlock;
|
对于自定义过渡动画的方法:
-(void)setDrawerVisualStateBlock:(void(^)(MMDrawerController * drawerController, MMDrawerSide drawerSide, CGFloat percentVisible))drawerVisualStateBlock;
回调block中会传递进来侧边栏显示完成的百分比,并且在侧边栏出现过程中,这个回调block会被不停刷新调用,开发者可以直接在其中对要过渡的属性进行设置,例如透明度的渐变动画,示例如下:
1 2 3 4 5 6 7 8 9 10 11 12
| [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时,开发者可以导入MMDrawerController+Subclass.h文件,这个文件中提供了许多控制器的监听方法供开发者重写,解析如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| -(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的辅助类,这个类可以创建三道杠的菜单按钮。其中方法如下:
1 2 3 4 5 6
| -(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,这个类中封装好了许多动画效果,开发者可以直接使用,示例如下:
1 2
| [rootController setDrawerVisualStateBlock:[MMDrawerVisualState slideAndScaleVisualStateBlock]];
|
MMDrawerVisualState中所提供的动画模板列举如下:
1 2 3 4 5 6 7 8
| +(MMDrawerControllerDrawerVisualStateBlock)slideAndScaleVisualStateBlock;
+(MMDrawerControllerDrawerVisualStateBlock)slideVisualStateBlock;
+(MMDrawerControllerDrawerVisualStateBlock)swingingDoorVisualStateBlock;
+(MMDrawerControllerDrawerVisualStateBlock)parallaxVisualStateBlockWithParallaxFactor:(CGFloat)parallaxFactor;
|
五、MMDrawerController无法完成的需求
为了确保MMDrawerController库的轻量级,其作者在设计时也做了功能上的取舍权衡,MMDrawerController无法完成以下需求:
1.上边栏与下边栏。
2.同时展示左边栏与又边栏。
3.无法设置显示一个最小的抽屉宽度。
4.不能支持UITabBarController容器。
5.不能在中心视图控制器之上呈现侧边栏视图。
专注技术,热爱生活,交流技术,也做朋友。
——珲少 QQ群:203317592