今天要自定義寫一個帶有左右兩邊側滑菜單欄的視圖控制器,要求手勢滑動
思路呢就是
一,現在storyboard上搭建好界面,比如:UITarbarController UINavigationController ?UIViewController
二, 新建左右兩個側滑控制器
.h
#import
@interfaceLeftSideVC :UITableViewController
@property(nonatomic,copy)void(^exitLeftSideblock)();
@end
.m
#import"LeftSideVC.h"
@implementationLeftSideVC
- (void)viewDidLoad{
[superviewDidLoad];
[self.tableViewregisterClass:[UITableViewCellclass]forCellReuseIdentifier:@"sideCell"];
}
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{
return20;
}
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
UITableViewCell* cell = [tableViewdequeueReusableCellWithIdentifier:@"sideCell"forIndexPath:indexPath];
cell.backgroundColor= [UIColororangeColor];
cell.textLabel.text= [NSStringstringWithFormat:@"我是第%ld行",indexPath.row];
returncell;
}
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath{
NSLog(@"被點擊了第%ld行",indexPath.row);
if(self.exitLeftSideblock)self.exitLeftSideblock();
}
@end
三,在主控制器上繼承自UISideViewController
.h
#import"WJSideViewController.h"
@interfaceOneViewController :WJSideViewController
@end
.m
#import"OneViewController.h"
#import"LeftSideVC.h"
#import"RightSideVc.h"
@interfaceOneViewController()
@end
@implementationOneViewController
- (void)viewDidLoad {
[superviewDidLoad];
self.navigationItem.rightBarButtonItem= [[UIBarButtonItemalloc]initWithTitle:@"向左側滑"style:UIBarButtonItemStylePlaintarget:selfaction:@selector(leftSide)];
//創建側滑出來的控制器
RightSideVC* vc = [[RightSideVCalloc]init];
//設置側滑出來的View的寬度,小于屏幕寬度
vc.view.frame=CGRectMake(0,0,150,0);
//設置左側的控制器
[selfsetRightSideVC:vc];
//側滑控制器-退出側滑狀態的代碼塊
__weaktypeof(self) weakSelf =self;
vc.exitRightSideblock= ^{
[weakSelfleftSide];
};
//設置向右側滑
self.navigationItem.leftBarButtonItem= [[UIBarButtonItemalloc]initWithTitle:@"向右側滑"style:UIBarButtonItemStylePlaintarget:selfaction:@selector(rightSide)];
LeftSideVC* vc1 = [[LeftSideVCalloc]init];
vc1.view.frame=CGRectMake(0,0,250,0);
//設置左側的控制器
[selfsetLeftSideVC:vc1];
vc1.exitLeftSideblock= ^{
[weakSelfrightSide];
};
}
-(void)leftSide{
[selfsideAnimateDuration:0.25SideDirection:WJSideDirectionLeft];
}
-(void)rightSide{
[selfsideAnimateDuration:0.25SideDirection:WJSideDirectionRight];
}
@end
四,在sideViewController里面實現側滑功能
.h
#import
typedefenum{
WJSideDirectionRight,
WJSideDirectionLeft,
}WJSideDirection;
@interfaceWJSideViewController :UIViewController
/**側滑并設置側滑動畫時間*/
-(void)sideAnimateDuration:(NSTimeInterval)duration SideDirection:(WJSideDirection)sideDirectionType;
/**設置左側的控制器*/
-(void)setLeftSideVC:(UIViewController*)leftSideVC;
/**設置右側的控制器*/
-(void)setRightSideVC:(UIViewController*)rightSideVC;
@end
.m?
#import"WJSideViewController.h"
staticCGFloatconstkSideDistanceRatio =0.55;//滑出0.55倍View的寬度時,松開手指,會自動滑出
@interfaceWJSideViewController()
@property(nonatomic,strong)UIView* leftSideView;//左側滑出的View
@property(nonatomic,strong)UIView* rightSideView;//右側劃出的View
@property(nonatomic,strong)UIViewController* leftSideVC;//左側的控制器
@property(nonatomic,strong)UIViewController* rightSideVC;//右側的控制器
@property(assign,nonatomic)WJSideDirectionsideDirectionType;//側滑的方向
@property(assign,nonatomic)BOOLisSide;//滑出狀態
@end
@implementationWJSideViewController
#pragma mark -生命周期方法
- (void)viewDidLoad{
[superviewDidLoad];
[self.viewaddGestureRecognizer:[[UIPanGestureRecognizeralloc]initWithTarget:selfaction:@selector(wj_panGesture:)]];
UITapGestureRecognizer* tap = [[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(wj_tapGesture:)];
[self.viewaddGestureRecognizer:tap];
tap.delegate=self;
}
- (void)viewDidDisappear:(BOOL)animated{
[superviewDidDisappear:animated];
[selfhiddenSideView];
}
- (void)hiddenSideView{
if(self.leftSideVC) {
self.leftSideView.hidden=YES;
}
if(self.rightSideVC) {
self.rightSideView.hidden=YES;
}
}
#pragma mark -內部方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer{
if([gestureRecognizerisKindOfClass:[UIPanGestureRecognizerclass]]) {
returnYES;
}
returnYES;
}
- (UIView*)leftSideView{
returnself.leftSideVC.view;
}
- (UIView*)rightSideView{
returnself.rightSideVC.view;
}
- (void)wj_tapGesture:(UITapGestureRecognizer*)tap{
if(self.isSide) {
[selfsideAnimateDuration:0.25SideDirection:_sideDirectionType];
self.isSide=NO;
}
}
- (void)wj_panGesture:(UIPanGestureRecognizer*)pan{
CGPointtranslation = [pantranslationInView:pan.view];
if(pan.state==UIGestureRecognizerStateChanged) {
CGPointpoint = [self.viewconvertPoint:self.view.frame.origintoView:[UIApplicationsharedApplication].keyWindow];
if(!self.isSide) {
if(self.leftSideVC&& point.x>=0&& translation.x=0){
_sideDirectionType=WJSideDirectionLeft;
self.leftSideView.hidden=NO;
[selfsideDistance:translation.x];
}elseif(self.rightSideVC&& point.x<=0&&- translation.x
_sideDirectionType=WJSideDirectionRight;
self.rightSideView.hidden=NO;
[selfsideDistance:translation.x];
}
}else{
if(self.leftSideVC&& point.x>=0&& translation.x<=0){
_sideDirectionType=WJSideDirectionLeft;
[selfsideDistance:(self.leftSideView.bounds.size.width+ translation.x)];
}elseif(self.rightSideVC&& point.x<=0&&translation.x>=0){
_sideDirectionType=WJSideDirectionRight;
self.rightSideView.hidden=NO;
[selfsideDistance:(-self.rightSideView.bounds.size.width+ translation.x)];
}
}
}elseif(pan.state==UIGestureRecognizerStateEnded) {
CGPointpoint = [self.viewconvertPoint:self.view.frame.origintoView:[UIApplicationsharedApplication].keyWindow];
if(_sideDirectionType!=WJSideDirectionRight) {
if(point.x>=0&& point.x>=self.leftSideView.bounds.size.width*kSideDistanceRatio){
[selfsideDistance:self.leftSideView.bounds.size.width];
[UIApplicationsharedApplication].statusBarStyle=UIStatusBarStyleLightContent;
self.isSide=YES;
}else{
[UIViewanimateWithDuration:0.25animations:^{
[selfsideDistance:0];
}];
[UIApplicationsharedApplication].statusBarStyle=UIStatusBarStyleDefault;
self.isSide=NO;
}
}else{
if( point.x<=0&& -point.x>=self.rightSideView.bounds.size.width*kSideDistanceRatio){
[selfsideDistance:-self.rightSideView.bounds.size.width];
[UIApplicationsharedApplication].statusBarStyle=UIStatusBarStyleLightContent;
self.isSide=YES;
}else{
[UIViewanimateWithDuration:0.25animations:^{
[selfsideDistance:0];
}];
[UIApplicationsharedApplication].statusBarStyle=UIStatusBarStyleDefault;
self.isSide=NO;
}
}
}
}
- (void)sideDistance:(CGFloat)distance{
for(UIView* viewin[UIApplicationsharedApplication].keyWindow.subviews) {
view.transform=CGAffineTransformMakeTranslation(distance,0);
}
}
#pragma mark -對外接口
- (void)sideAnimateDuration:(NSTimeInterval)duration SideDirection:(WJSideDirection)sideDirectionType{
if([UIApplicationsharedApplication].statusBarStyle==UIStatusBarStyleDefault){
[UIApplicationsharedApplication].statusBarStyle=UIStatusBarStyleLightContent;
}else{
[UIApplicationsharedApplication].statusBarStyle=UIStatusBarStyleDefault;
}
if(self.isSide) {
self.isSide=NO;
[UIViewanimateWithDuration:durationanimations:^{
for(UIView* viewin[UIApplicationsharedApplication].keyWindow.subviews) {
view.transform=CGAffineTransformIdentity;
}
}completion:^(BOOLfinished) {
[selfhiddenSideView];
}];
return;
}
self.isSide=YES;
if(sideDirectionType ==WJSideDirectionLeft){
self.rightSideView.hidden=NO;
}else{
self.leftSideView.hidden=NO;
}
CGFloat_sideWidth = (sideDirectionType ==WJSideDirectionRight) ?self.leftSideView.frame.size.width: -self.rightSideView.frame.size.width;
[UIViewanimateWithDuration:durationanimations:^{
[selfsideDistance:_sideWidth];
}];
}
- (void)setLeftSideVC:(UIViewController*)leftSideVC{
_leftSideVC= leftSideVC;
[[UIApplicationsharedApplication].keyWindowaddSubview:self.leftSideView];
CGRectrect =self.leftSideView.bounds;
CGFloatsideWidth =self.leftSideView.bounds.size.width;
sideWidth = rect.size.width;
self.leftSideView.frame=CGRectMake(- rect.size.width,0, rect.size.width, [UIScreenmainScreen].bounds.size.height);
}
- (void)setRightSideVC:(UIViewController*)rightSideVC{
_rightSideVC= rightSideVC;
[[UIApplicationsharedApplication].keyWindowaddSubview:self.rightSideView];
CGRectrect =self.rightSideView.bounds;
CGFloatsideWidth =self.rightSideView.bounds.size.width;
sideWidth = rect.size.width;
self.rightSideView.frame=CGRectMake([UIScreenmainScreen].bounds.size.width,0, rect.size.width, [UIScreenmainScreen].bounds.size.height);
}
最后的運行效果圖:
最后,群里面很多iOS開發志同道合的伙伴,感興趣的朋友歡迎加入進來,QQ:580284575