QQ音乐侧滑栏的实现

对于现有的实现侧滑栏的方式,主要有两种,一种是将侧滑栏作为视图控制器,用视图控制器控制侧滑栏,这个网上有很多写好的案例,视图控制器实现侧滑栏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的滑动,这个涉及到手势的代理,后面会附上。

你可能感兴趣的:(QQ音乐侧滑栏的实现)