本文是我的處女篇啦礼烈,全文參考官方文檔,基于自己公司項(xiàng)目所寫勋篓。在這里實(shí)現(xiàn)側(cè)拉功能吧享,使用的是MMDrawerController第三方庫如,有不正確的地方譬嚣,還請留下一筆耙蔑,以做參考
Mutual Mobile Drawer Controller
https://github.com/mutualmobile/MMDrawerController
MMDrawerControlleris側(cè)抽屜導(dǎo)航容器視圖控制器設(shè)計(jì)用于支持應(yīng)用程序利用側(cè)抽屜方式越來越多。這個庫的目的是完全支持側(cè)抽屜式導(dǎo)航在一個輕量級的孤荣、集中的方法甸陌,在呈現(xiàn)和解聘抽屜提供自定義動畫的能力。
Documentation
Official appledoc documentation can be found atCocoaDocs.
安裝 MMDrawerController
在項(xiàng)目中安裝 MMDrawerController通過CocoaPods:
pod'MMDrawerController','~> 0.5.7'
創(chuàng)建a drawer controller
AppDelegate.m ->- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions
self.sideViewController = [[SideViewController alloc] init];
self.homeViewController = [[HomeViewController alloc] init];
UINavigationController *navigationControllerHome = [[UINavigationController alloc] initWithRootViewController:self.homeViewController];
UINavigationController *navigationControllerLeft = [[UINavigationController alloc]initWithRootViewController:self.sideViewController];
self.drawerController = [[MMDrawerController alloc]
initWithCenterViewController:navigationControllerHome
leftDrawerViewController:navigationControllerLeft
rightDrawerViewController:nil];
[self.drawerController setRestorationIdentifier:@"MMDrawer"];
[navigationController setRestorationIdentifier:@"MMExampleCenterNavigationControllerRestorationKey"];
[self.sideViewController setRestorationIdentifier:@"MMExampleLeftSideDrawerController"];
[self.drawerController setMaximumLeftDrawerWidth:SIDE_OFFSET];
self.drawerController.showsShadow = NO;
self.drawerController.shouldStretchDrawer = NO;
[self.drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeAll];
[self.drawerController setCloseDrawerGestureModeMask:MMCloseDrawerGestureModeAll];
[self.drawerController
setDrawerVisualStateBlock:^(MMDrawerController *drawerController, MMDrawerSide drawerSide, CGFloat percentVisible) {
MMDrawerControllerDrawerVisualStateBlock block;
block = [MMDrawerVisualState parallaxVisualStateBlockWithParallaxFactor:2.0f];
if(block){
block(drawerController, drawerSide, percentVisible);
}
}];
實(shí)現(xiàn)側(cè)拉效果
UIGestureRecognizer Support
MMOpenDrawerGestureMode
MMOpenDrawerGestureModePanningNavigationBar: 用戶清掃導(dǎo)航欄打開側(cè)邊欄盐股;
MMOpenDrawerGestureModePanningCenterView: 用戶清掃中間的屏幕打開側(cè)邊欄钱豁;
MMOpenDrawerGestureModeBezelPanningCenterView: 用戶清掃底部20個地方打開側(cè)邊欄;
MMOpenDrawerGestureModeCustom:開發(fā)者可以提供一個回調(diào)塊來確定該手勢是否應(yīng)該被識別疯汁。
MMCloseDrawerGestureMode
MMCloseDrawerGestureModePanningNavigationBar:用戶清掃頂部導(dǎo)航欄關(guān)閉側(cè)邊欄牲尺;
MMCloseDrawerGestureModePanningCenterView: 用戶清掃中間的視圖關(guān)閉側(cè)邊欄;
MMCloseDrawerGestureModeBezelPanningCenterView:用戶清掃底部中間視圖關(guān)閉側(cè)邊欄幌蚊;?
MMCloseDrawerGestureModeTapNavigationBar:用戶點(diǎn)擊頂部導(dǎo)航欄關(guān)閉側(cè)邊欄谤碳;?
MMCloseDrawerGestureModeTapCenterView: 用戶點(diǎn)擊中間的視圖關(guān)閉側(cè)邊欄;
MMCloseDrawerGestureModePanningDrawerView:用戶清掃側(cè)邊欄關(guān)閉側(cè)邊欄溢豆;
MMCloseDrawerGestureModeCustom: 開發(fā)者可以提供一個回調(diào)塊來確定該手勢是否應(yīng)該被識別蜒简。
Custom Gesture Recognizer Support
從版本0.3.0┊,你現(xiàn)在可以自定義一個手勢使用setGestureShouldRecognizeTouchBlock提供一個回調(diào)方法漩仙。該方法提供了三個參數(shù)-抽屜控制器搓茬,手勢和觸摸。作為開發(fā)人員队他,您負(fù)責(zé)檢查這些元素卷仑,并確定該手勢是否應(yīng)該被確認(rèn)。注塊僅供參考如果你設(shè)置了openDrawerGestureModeMask 包含了 MMOpenDrawerGestureModeCustom麸折,你可以設(shè)置代碼塊如下锡凝。
[myDrawerController
setGestureShouldRecognizeTouchBlock:^BOOL(MMDrawerController *drawerController, UIGestureRecognizer *gesture, UITouch *touch) {
BOOL shouldRecognizeTouch = NO;
if(drawerController.openSide == MMDrawerSideNone &&
[gesture isKindOfClass:[UIPanGestureRecognizer class]]){
UIView * customView = [drawerController.centerViewController myCustomSubview];
CGPoint location = [touch locationInView:customView];
shouldRecognizeTouch = (CGRectContainsPoint(customView.bounds, location));
}
return shouldRecognizeTouch;
}];
方法drawerVisualStateBlock的含義
當(dāng)一個抽屜狀態(tài)更新時,設(shè)置一個回調(diào)函數(shù)垢啼。
這一塊是負(fù)責(zé)更新抽屜狀態(tài)窜锯,和抽屜控制器動畫處理狀態(tài)轉(zhuǎn)變〔布校回調(diào)函數(shù)將被調(diào)用當(dāng)抽屜被打開或關(guān)閉衬浑,以及當(dāng)用戶打開抽屜。這一塊是不負(fù)責(zé)直接做動畫放刨,而只是更新的視圖屬性(alpha, anchor point, transform,等)工秩。注意,如果`shouldStretchDrawer`是yes进统,`percentVisible`要大于1助币。如果` shouldStretchDrawer`設(shè)置為no,` percentVisible `不大于1
`shouldStretchDrawer` is set to YES, it is possible for `percentVisible` to be greater than 1.0. If `shouldStretchDrawer` is set to NO, `percentVisible` will never be greater than 1.0.
注意螟碎,當(dāng)抽屜完成開啟或關(guān)閉眉菱,側(cè)抽屜控制器視圖將具有以下性能復(fù)位:
- alpha: 1.0
- transform: CATransform3DIdentity
- anchorPoint: (0.5,0.5)
@param drawerVisualStateBlock block塊被調(diào)用執(zhí)行更新抽屜的視覺特性。` percentVisible`表示當(dāng)前可見的抽屜與抽屜空間的大小掉分,空間被定義為屏幕上的maxmimum抽屜寬度的邊緣俭缓。注意克伊,你已經(jīng)進(jìn)入drawercontroller,這將允許您更新像側(cè)抽屜層定位點(diǎn)华坦。
視圖恢復(fù)的實(shí)現(xiàn)
- (UIViewController *)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder
{
NSString * key = [identifierComponents lastObject];
if([key isEqualToString:@"MMDrawer"]){
return self.window.rootViewController;
}
else if ([key isEqualToString:@"MMExampleCenterNavigationControllerRestorationKey"]) {
return ((MMDrawerController *)self.window.rootViewController).centerViewController;
}
else if ([key isEqualToString:@"MMExampleLeftNavigationControllerRestorationKey"]) {
return ((MMDrawerController *)self.window.rootViewController).leftDrawerViewController;
}
else if ([key isEqualToString:@"MMExampleLeftSideDrawerController"]){
UIViewController * leftVC = ((MMDrawerController *)self.window.rootViewController).leftDrawerViewController;
if([leftVC isKindOfClass:[UINavigationController class]]){
return [(UINavigationController*)leftVC topViewController];
}
else {
return leftVC;
}
}
return nil;
}
二級頁面滑動返回到一級界面
SideViewController.h
實(shí)現(xiàn)主界面向左滑動時進(jìn)入側(cè)邊欄愿吹,二級頁面返回進(jìn)入主頁面,在
- (void)pushViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[HomeViewController class]]) {
[User currentUser].isHome = YES;
[self.mm_drawerController closeDrawerAnimated:YES completion:nil];
return;
}
[User currentUser].isHome = NO;
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[self.mm_drawerController toggleDrawerSide:MMDrawerSideLeft animated:YES completion:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:delegate.homeViewController];
[self.mm_drawerController setCenterViewController:nav withCloseAnimation:NO completion:^(BOOL finished) {
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[delegate.homeViewController.navigationController pushViewController:viewController animated:YES];
}];
self.seletedIndex = 0;
}
方法toggleDrawerSide的含義
調(diào)用這個方法基于進(jìn)入`drawer`惜姐。
請注意犁跪,如果您試圖切換抽屜關(guān)閉,而另一個是開放的歹袁,沒有什么會發(fā)生坷衍。例如,如果你進(jìn)入MMDrawerSideLeft頁面条舔,但正確的抽屜是開著的枫耳,什么都不會發(fā)生。此外逞刷,完成塊將被稱為完成標(biāo)志設(shè)置為不嘉涌。
@param ?切換drawerSide The `MMDrawerSide` . 它的值不能是 `MMDrawerSideNone`.
@param 動畫決定`drawer`是否應(yīng)該切換動畫。
@param 當(dāng)切換完成的時候調(diào)用這個block塊夸浅,或者如果沒有切換發(fā)生仑最。
demo:在首頁點(diǎn)擊導(dǎo)航欄最左側(cè)的按鈕,進(jìn)入左側(cè)邊欄帆喇,實(shí)現(xiàn)如下:
[self.mm_drawerController toggleDrawerSide:MMDrawerSideLeft animated:YES completion:nil];