对于现有的实现侧滑栏的方式,主要有两种,一种是将侧滑栏作为视图控制器,用视图控制器控制侧滑栏,这个网上有很多写好的案例,视图控制器实现侧滑栏demo这里有直接的项目代码可供参考。
另外一种就是使用view和滑动手势实现的侧滑栏,视图层解释,将侧滑栏放在视图底层,然后主界面放在上层,给主界面添加滑动手势,右滑的时候改变这界面的位置(缩放在右侧),这样底层的View,也就是侧滑栏就显示出来了。不多说了,贴代码:
import "MSMainVC.h"
/* main views */
#import "MSSliderView.h"
#import "MSMainLeftView.h"
用这个来判断滑动的方向
typedef enum :NSInteger {
kCameraMoveDirectionNone = 10,
kCameraMoveDirectionRight,
kCameraMoveDirectionLeft,
kCameraMoveDirectionUp,
kCameraMoveDirectionDown
} CameraMoveDirection;
设置滑动之后右边显示的宽度
static const CGFloat kRightWidth = 60.0f;
设置判断滑动的最小位移
static const CGFloat kGestureMinimumTranslation = 20.0;
@interface MSMainVC () {
CameraMoveDirection direction;
}
@property (nonatomic, strong) UIView *mainView;
@property (nonatomic, strong) UIView *leftView;
滑动之后给的一个遮盖层
@property (nonatomic, strong) UIWindow *progressWindow;
@end
@implementation MSMainVC
#pragma mark - lifeCycle of view
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBar.hidden = YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self createUI];
[self createFooterWindow];
}
#pragma mark - createUI
- (void)createUI {
[self createLeftView];
[self createMainView];
[self createWindowProgress];
}
- (void)createLeftView {
MSMainLeftView *leftV = [[MSMainLeftView alloc] initWithFrame:CGRectMake(0, 0, WIDTH - kRightWidth, HEIGHT)];
[self.view addSubview:leftV];
_leftView = leftV;
}
- (void)createMainView {
_contentView = [[MSSliderView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:_contentView];
_mainView = _contentView;
添加滑动手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self.contentView addGestureRecognizer:pan];
}
创建遮盖层
- (void) createWindowProgress {
_progressWindow = [[UIWindow alloc] initWithFrame:self.view.bounds];
_progressWindow.windowLevel = UIWindowLevelAlert + 2;
[_progressWindow makeKeyAndVisible];
_progressWindow.backgroundColor = WCDarkBlue;
_progressWindow.alpha = 0;
添加用于还原的手势,可以根据需求进行选择
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTap)];
[_progressWindow addGestureRecognizer:tap];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(resetPan:)];
[_progressWindow addGestureRecognizer:pan];
}
#pragma mark - actions
- (void) resetPan: (UIPanGestureRecognizer *)gesture {
[self tapTap];
}
- (void) tapTap {
[UIView animateWithDuration:0.3 animations:^{
self.mainView.frame = self.view.bounds; // 还原 mainView 的位置
[self setProgressWindowWithMainX];
}];
}
- (void) pan:(UIPanGestureRecognizer *)gesture {
CGPoint translation = [gesture translationInView:self.mainView];
// 判断滑动方向
if (gesture.state == UIGestureRecognizerStateBegan) {
direction = kCameraMoveDirectionNone;
} else if (gesture.state == UIGestureRecognizerStateChanged && direction == kCameraMoveDirectionNone) {
direction = [self determineCameraDirectionIfNeeded:translation];
}
if (direction == kCameraMoveDirectionRight) { // 向右滑
NSLog(@"start moving right");
if (gesture.state == UIGestureRecognizerStateChanged && self.mainView.x < 0) {
NSLog(@"moving boundary");
}
[self setLeftFrameWithOffsetX:translation.x];
if (gesture.state == UIGestureRecognizerStateEnded) {
// 滑动结束给判断
if (self.mainView.frame.origin.x > WIDTH * 0.3 ) {
[self showLeftView];
} else {
[self tapTap];
}
}
} else if (direction == kCameraMoveDirectionLeft) { // 向左滑
NSLog(@"start moving left");
} else if (direction == kCameraMoveDirectionDown) {
NSLog(@"start moving down");
} else if (direction == kCameraMoveDirectionUp) {
NSLog(@"start moving up");
}
[gesture setTranslation:CGPointZero inView:self.mainView];
}
#pragma mark --根据偏移量计算MainV的frame
// 显示左侧view - 点击
- (void) showLeftView {
CGFloat target = (WIDTH - kRightWidth);
CGFloat offset = target - self.mainView.frame.origin.x;
[UIView animateWithDuration:0.5 animations:^{
self.mainView.frame = [self frameWithOffsetX:offset];
[self setProgressWindowWithMainX];
}];
}
// 显示左侧view - 滑动
- (void) setLeftFrameWithOffsetX : (CGFloat)offsetX {
self.mainView.frame = [self frameWithOffsetX:offsetX];
[self setProgressWindowWithMainX];
}
- (CGRect) frameWithOffsetX:(CGFloat)offsetX {
CGRect frame = self.mainView.frame;
frame.origin.x += offsetX;
return frame;
}
- (void) setProgressWindowWithMainX {
CGFloat mainX = self.mainView.frame.origin.x;
CGRect frame = self.progressWindow.frame;
frame.origin.x = mainX;
_progressWindow.frame = frame;
_progressWindow.alpha = 0.6 * (mainX / (WIDTH - 80));
}
#pragma mark - private func
获取滑动方向,这里直接贴的代码,就不做多的介绍了,方向是根据x和y的偏移量及方向进行判断的
- (CameraMoveDirection) determineCameraDirectionIfNeeded:(CGPoint)translation {
if (direction != kCameraMoveDirectionNone)
return direction;
// determine if horizontal swipe only if you meet some minimum velocity
if (fabs(translation.x) > kGestureMinimumTranslation) {
BOOL gestureHorizontal = NO;
if (translation.y == 0.0)
gestureHorizontal = YES;
else
gestureHorizontal = (fabs(translation.x / translation.y) > 5.0);
if (gestureHorizontal) {
if (translation.x > 0.0)
return kCameraMoveDirectionRight;
else
return kCameraMoveDirectionLeft;
} else if(fabs(translation.y) > kGestureMinimumTranslation)
{
BOOL gestureVertical = NO;
if(translation.x == 0.0)
gestureVertical = YES;
else
gestureVertical = (fabs(translation.y / translation.x) > 5.0);
if(gestureVertical)
{
if(translation.y > 0.0)
return kCameraMoveDirectionDown;
else
return kCameraMoveDirectionUp;
}
}
}
return direction;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
这里只是实现了简单的两个View的滑动,如果在主界面上添加了左右滑动的scrollView,怎么在scrollView在最左边的时候向右滑能打开侧滑栏,向左滑的时候是进行scrollView的滑动,这个涉及到手势的代理,后面会附上。