抽屜效果目前比較有名的有第三方RESideMenu和MMDrawerController。但是項(xiàng)目要求抽屜效果為拉出形式邑跪,并且要有黑色透明遮罩層粉铐,然后在GitHub發(fā)現(xiàn)了一個(gè)更好用的庫ViewDeck
ViewDeck
- 支持左邊和右邊側(cè)邊欄
- 抽屜拉出效果,帶有黑色透明遮罩層
- 支持點(diǎn)擊和滑動(dòng)打開溺拱、關(guān)閉側(cè)邊欄
- 側(cè)邊欄顯示內(nèi)容尺寸可以控制
- 省心省力逃贝,簡(jiǎn)潔好用谣辞,快速集成
目前側(cè)滑關(guān)閉功能僅在示例demo里,作者并未發(fā)布到cocoapods issues沐扳。通過pods方式導(dǎo)入的并沒有側(cè)滑關(guān)閉功能泥从,如需側(cè)滑功能,請(qǐng)手動(dòng)導(dǎo)入本demo或GitHub demo ViewDeck文件夾 —20190105
1.配置側(cè)邊欄
UITabBarController *tarBarCtr=[[UITabBarController alloc]init];
[tarBarCtr setViewControllers:[NSArray arrayWithObjects:centNvi,centSecNvi, nil]];
_rootTabbarCtrV=tarBarCtr;
//左邊view 采用xib多種形式研究
LeftSideViewController *leftVC =[[LeftSideViewController alloc]initWithNibName:@"LeftSideViewController" bundle:[NSBundle mainBundle]];
//右邊
RightSideViewController *rightView=[[RightSideViewController alloc]init];
UINavigationController *rightNvi=[[UINavigationController alloc]initWithRootViewController:rightView];
//配置側(cè)邊欄
IIViewDeckController *viewDeckController =[[IIViewDeckController alloc]initWithCenterViewController:_rootTabbarCtrV leftViewController:leftVC rightViewController:rightNvi];
//只有左側(cè)邊欄
// IIViewDeckController *viewDeckController =[[IIViewDeckController alloc]initWithCenterViewController:_rootTabbarCtrV leftViewController:leftVC];
viewDeckController.delegate=self;
self.window.rootViewController=viewDeckController;
2.首頁點(diǎn)擊側(cè)邊欄按鈕和跳轉(zhuǎn)下一頁
通過openSide:(IIViewDeckSide)方法可以左沪摄、右側(cè)邊欄; panningEnabled屬性僅可以控制滑動(dòng)打開關(guān)閉躯嫉,但點(diǎn)擊關(guān)閉和openSide:打開是不在這個(gè)屬性的控制范圍內(nèi)的
typedef NS_ENUM(NSInteger, IIViewDeckSide) {
IIViewDeckSideNone = 0, /// This identifies no side, basically meaning that neither the left nor the right side is relevant.
IIViewDeckSideLeft, /// This identifies the left view controller of an IIViewDeckController
IIViewDeckSideRight, /// This identifies the right view controller of an IIViewDeckController
IIViewDeckSideUnknown = IIViewDeckSideNone, /// This has the same logic as IIViewDeckSideNone but means that the side is yet unknown.
IIViewDeckLeftSide __deprecated_enum_msg("Use IIViewDeckSideLeft instead.") = IIViewDeckSideLeft,
IIViewDeckRightSide __deprecated_enum_msg("Use IIViewDeckSideRight instead.") = IIViewDeckSideRight,
};
//點(diǎn)擊打開左側(cè)側(cè)邊欄
-(void)actionOfTapLeftEvent{
[self.viewDeckController openSide:IIViewDeckSideLeft animated:YES];
}
//跳轉(zhuǎn)下一頁
-(void)actionOfTapRightEvent{
InfoViewController *infoView=[[InfoViewController alloc]init];
[infoView setHidesBottomBarWhenPushed:YES];
//不需要類似RESideMenu把panGestureEnabled關(guān)閉
[self.navigationController pushViewController:infoView animated:YES];
}
3.側(cè)邊欄顯示內(nèi)容寬度設(shè)置和跳轉(zhuǎn)
通過preferredContentSize屬性設(shè)置側(cè)邊欄的內(nèi)容寬度尺寸
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//ViewDeck默認(rèn)高度始終是視圖控制器本身的高度上
self.preferredContentSize = CGSizeMake(ScreenWidth/3*2, ScreenHeight);
self.view.backgroundColor=[UIColor whiteColor];
}
- (IBAction)goNextView:(UIButton *)sender {
/**
關(guān)閉側(cè)邊欄
*/
[self.viewDeckController closeSide:YES];
UINavigationController *navCtr= ((AppDelegate*)[UIApplication sharedApplication].delegate).rootTabbarCtrV.selectedViewController;
InfoViewController *infoView=[[InfoViewController alloc]init];
[infoView setHidesBottomBarWhenPushed:YES];
[navCtr pushViewController:infoView animated:YES];
}
4.打開關(guān)閉IIViewDeckControllerDelegate代理
可以通過代理控制某些情況下才能打開側(cè)邊欄等情況,也可以做些打開關(guān)閉時(shí)的相關(guān)操作
//即將打開側(cè)邊欄杨拐。 return NO 側(cè)滑無法打開祈餐,但通過openSide:方法可以強(qiáng)行打開;
- (BOOL)viewDeckController:(IIViewDeckController *)viewDeckController willOpenSide:(IIViewDeckSide)side;
//已經(jīng)打開側(cè)邊欄哄陶》簦可以做一些后續(xù)操作
- (void)viewDeckController:(IIViewDeckController *)viewDeckController didOpenSide:(IIViewDeckSide)side;
//即將關(guān)閉
- (BOOL)viewDeckController:(IIViewDeckController *)viewDeckController willCloseSide:(IIViewDeckSide)side;
//即將打開
- (void)viewDeckController:(IIViewDeckController *)viewDeckController didCloseSide:(IIViewDeckSide)side;
4.關(guān)閉側(cè)邊欄時(shí),可滑動(dòng)關(guān)閉
IIViewDeckController.mm 源碼文件中屋吨,decorationTapGestureRecognizer蜒谤、dismissGestureRecognizer是關(guān)閉側(cè)邊欄的手勢(shì),其中一個(gè)是點(diǎn)擊關(guān)閉一個(gè)是新加的滑動(dòng)關(guān)閉
@property (nonatomic) UIScreenEdgePanGestureRecognizer *leftEdgeGestureRecognizer;
@property (nonatomic) UIScreenEdgePanGestureRecognizer *rightEdgeGestureRecognizer;
@property (nonatomic) UITapGestureRecognizer *decorationTapGestureRecognizer;
//滑動(dòng)關(guān)閉側(cè)邊欄
@property (nonatomic) UIPanGestureRecognizer *dismissGestureRecognizer;
下面這個(gè)庫是個(gè)古董級(jí)的至扰,不過功能齊全鳍徽,實(shí)際使用除了個(gè)別需要注意外也還不錯(cuò)。歡迎體驗(yàn): REFrostedViewController
REFrostedViewController
- 側(cè)邊欄顯示內(nèi)容尺寸可以控制
- 抽屜拉出效果敢课,帶有黑色透明遮罩層
- 可以側(cè)滑關(guān)閉(重點(diǎn))
- 缺點(diǎn):僅支持單邊側(cè)邊欄(左邊或右邊)
- 缺點(diǎn):顯示側(cè)邊欄時(shí)需要手動(dòng)實(shí)現(xiàn)滑動(dòng)手勢(shì)阶祭,會(huì)有隱藏隱患
- 缺點(diǎn):拉出和關(guān)閉時(shí),黑色遮罩并不完美
- 缺點(diǎn):已經(jīng)停止維護(hù)了三四年了(老古董了)
1.配置側(cè)邊欄
//側(cè)邊欄
REFMenuViewController *menuView = [[REFMenuViewController alloc]init];
REFrostedViewController *rostedViewController = [[REFrostedViewController alloc] initWithContentViewController:tarBarCtr menuViewController:menuView];
rostedViewController.direction = REFrostedViewControllerDirectionLeft;
rostedViewController.liveBlurBackgroundStyle = REFrostedViewControllerLiveBackgroundStyleDark;
rostedViewController.liveBlur = YES;
rostedViewController.limitMenuViewSize = YES;
rostedViewController.backgroundFadeAmount=0.5;
rostedViewController.delegate = self;
rostedViewController.menuViewSize=CGSizeMake(leftSideMeunWidth, ScreenHeight);
2.首頁點(diǎn)擊側(cè)邊欄按鈕和跳轉(zhuǎn)下一頁
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationItem.title=@"首頁";
UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithTitle:@"左邊欄" style:UIBarButtonItemStylePlain target:self action:@selector(actionOfTapLeftEvent:)];
self.navigationItem.leftBarButtonItem=leftBarButton;
UIBarButtonItem *rightBarButton=[[UIBarButtonItem alloc]initWithTitle:@"下一頁" style:UIBarButtonItemStylePlain target:self action:@selector(actionOfTapRightEvent)];
self.navigationItem.rightBarButtonItem=rightBarButton;
/**
如需要側(cè)滑顯示側(cè)邊欄翎猛,則要實(shí)現(xiàn)滑動(dòng)手勢(shì)
*/
[self.view addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognized:)]];
[self creatVC];
}
//點(diǎn)擊顯示側(cè)邊欄
-(void)actionOfTapLeftEvent:(UIButton *)sender{
[self.frostedViewController presentMenuViewController];
}
//滑動(dòng)顯示側(cè)邊欄
- (void)panGestureRecognized:(UIPanGestureRecognizer *)sender{
[self.frostedViewController panGestureRecognized:sender];
}
3.側(cè)邊欄關(guān)閉和跳轉(zhuǎn)
//跳轉(zhuǎn)下一頁
-(void)actionOfTapRightEvent{
/**
關(guān)閉右側(cè)側(cè)邊欄
*/
[self.frostedViewController hideMenuViewController];
UINavigationController *navCtr= ((AppDelegate*)[UIApplication sharedApplication].delegate).rootTabbarCtrV.selectedViewController;
REFInfoViewController *infoView=[[REFInfoViewController alloc]init];
[infoView setHidesBottomBarWhenPushed:YES];
[navCtr pushViewController:infoView animated:YES];
}
4.當(dāng)視圖內(nèi)含有UIScrollView時(shí)胖翰,會(huì)導(dǎo)致側(cè)滑失效,解決方案之一可以繼承UIScrollView并實(shí)現(xiàn)如下:
/**
* 重寫手勢(shì)切厘,如果是左滑萨咳,則禁用掉scrollview自帶的;右滑很少出現(xiàn)疫稿,此處未實(shí)現(xiàn)
*/
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
if([pan translationInView:self].x > 0.0f && self.contentOffset.x == 0.0f)
{
return NO;
}
}
return [super gestureRecognizerShouldBegin:gestureRecognizer];
}
最后小demo附上:ViewDeckStudy 內(nèi)含ViewDeck和REFrostedViewController使用