使用ICSDrawerController 实现侧滑功能

在ICSDrawerController 第三方上做了修改实现,QQ 点击头像打开关抽屉头像渐变的效果

- (void)hiddenHeadView:(hiddenHeadViewBlock)block;
@property(nonatomic,copy) hiddenHeadViewBlock hiddenBlock;
- (void)hiddenHeadView:(hiddenHeadViewBlock)block
{
self.hiddenBlock = block;
}

在拖拽滑动的手势方法中监听滑动的方法中来改变透明度

- (void)panGestureRecognized:(UIPanGestureRecognizer *)panGestureRecognizer
{
NSParameterAssert(self.leftView);
NSParameterAssert(self.centerView); UIGestureRecognizerState state = panGestureRecognizer.state;
CGPoint location = [panGestureRecognizer locationInView:self.view];
CGPoint velocity = [panGestureRecognizer velocityInView:self.view]; switch (state) { case UIGestureRecognizerStateBegan:
self.panGestureStartLocation = location;//记录当前的位置
if (self.drawerState == ICSDrawerControllerStateClosed) {
[self willOpen];
}
else {
[self willClose];
}
break; case UIGestureRecognizerStateChanged: { //每次拖拽滑动
CGFloat delta = 0.0f;
if (self.drawerState == ICSDrawerControllerStateOpening) {
delta = location.x - self.panGestureStartLocation.x;
}
else if (self.drawerState == ICSDrawerControllerStateClosing) {
delta = kICSDrawerControllerDrawerDepth - (self.panGestureStartLocation.x - location.x);
} CGRect l = self.leftView.frame;
CGRect c = self.centerView.frame;
if (delta > kICSDrawerControllerDrawerDepth) {
l.origin.x = 0.0f;
c.origin.x = kICSDrawerControllerDrawerDepth;
}
else if (delta < 0.0f) {
l.origin.x = kICSDrawerControllerLeftViewInitialOffset;
c.origin.x = 0.0f;
}
else {
// While the centerView can move up to kICSDrawerControllerDrawerDepth points, to achieve a parallax effect
// the leftView has move no more than kICSDrawerControllerLeftViewInitialOffset points
l.origin.x = kICSDrawerControllerLeftViewInitialOffset
- (delta * kICSDrawerControllerLeftViewInitialOffset) / kICSDrawerControllerDrawerDepth; c.origin.x = delta;
CGFloat alpha = - delta//2.6;
if (alpha > 1.0) {
alpha = 1.0;
}else if(alpha < ){
alpha = ;
}
//头像是否显示隐藏
self.hiddenBlock(alpha);
} self.leftView.frame = l;
self.centerView.frame = c; break;
} case UIGestureRecognizerStateEnded: { //拖拽结束 if (self.drawerState == ICSDrawerControllerStateOpening) {
CGFloat centerViewLocation = self.centerView.frame.origin.x;
if (centerViewLocation == kICSDrawerControllerDrawerDepth) {
// Open the drawer without animation, as it has already being dragged in its final position
[self setNeedsStatusBarAppearanceUpdate];
[self didOpen];
}
else if (centerViewLocation > self.view.bounds.size.width /
&& velocity.x > 0.0f) {
// Animate the drawer opening
[self animateOpening];
}
else {
// Animate the drawer closing, as the opening gesture hasn't been completed or it has
// been reverted by the user
[self didOpen];
[self willClose];
[self animateClosing];
} } else if (self.drawerState == ICSDrawerControllerStateClosing) {
CGFloat centerViewLocation = self.centerView.frame.origin.x;
if (centerViewLocation == 0.0f) {
// Close the drawer without animation, as it has already being dragged in its final position
[self setNeedsStatusBarAppearanceUpdate];
[self didClose];
}
else if (centerViewLocation < ( * self.view.bounds.size.width) /
&& velocity.x < 0.0f) {
// Animate the drawer closing
[self animateClosing];
}
else {
// Animate the drawer opening, as the opening gesture hasn't been completed or it has
// been reverted by the user
[self didClose]; // Here we save the current position for the leftView since
// we want the opening animation to start from the current position
// and not the one that is set in 'willOpen'
CGRect l = self.leftView.frame;
[self willOpen];
self.leftView.frame = l; [self animateOpening];
}
}
}
break; default:
break;
}
} #pragma mark - Animations
#pragma mark Opening animation
- (void)animateOpening
{
NSParameterAssert(self.drawerState == ICSDrawerControllerStateOpening);
NSParameterAssert(self.leftView);
NSParameterAssert(self.centerView); // Calculate the final frames for the container views
CGRect leftViewFinalFrame = self.view.bounds;
CGRect centerViewFinalFrame = self.view.bounds;
centerViewFinalFrame.origin.x = kICSDrawerControllerDrawerDepth; [UIView animateWithDuration:kICSDrawerControllerAnimationDuration
delay:
usingSpringWithDamping:kICSDrawerControllerOpeningAnimationSpringDamping
initialSpringVelocity:kICSDrawerControllerOpeningAnimationSpringInitialVelocity
options:UIViewAnimationOptionCurveLinear
animations:^{
self.centerView.frame = centerViewFinalFrame;
self.leftView.frame = leftViewFinalFrame;
self.hiddenBlock(); [self setNeedsStatusBarAppearanceUpdate];
}
completion:^(BOOL finished) {
[self didOpen];
}];
}
#pragma mark Closing animation
- (void)animateClosing
{
NSParameterAssert(self.drawerState == ICSDrawerControllerStateClosing);
NSParameterAssert(self.leftView);
NSParameterAssert(self.centerView); // Calculate final frames for the container views
CGRect leftViewFinalFrame = self.leftView.frame;
leftViewFinalFrame.origin.x = kICSDrawerControllerLeftViewInitialOffset;
CGRect centerViewFinalFrame = self.view.bounds; [UIView animateWithDuration:kICSDrawerControllerAnimationDuration
delay:
usingSpringWithDamping:kICSDrawerControllerClosingAnimationSpringDamping
initialSpringVelocity:kICSDrawerControllerClosingAnimationSpringInitialVelocity
options:UIViewAnimationOptionCurveLinear
animations:^{
self.centerView.frame = centerViewFinalFrame;
self.leftView.frame = leftViewFinalFrame;
self.hiddenBlock(); [self setNeedsStatusBarAppearanceUpdate];
}
completion:^(BOOL finished) {
[self didClose];
}];
}

给当前类扩充一个方法,拿到当前conroller的menuController

@interface UIViewController (ICSDrawerController)

//拿到当前conroller的menuController
//如果不存在,返回nil
@property (nonatomic, readonly) ICSDrawerController* menuController; @end
@implementation UIViewController (ICSDrawerController)

- (ICSDrawerController *)menuController {

    if (self.parentViewController == nil) {
return nil;
}else if ([self.parentViewController isKindOfClass:[ICSDrawerController class]]) {
return (ICSDrawerController* )self.parentViewController;
}else {
return self.parentViewController.menuController;
}
} @end

换皮肤功能使用 KVO 监听属性就可以实现,这里附上代码https://github.com/SummerHH/QQMenu


一个很好用的侧滑框架ICSDrawerController实现的 QQ 侧滑及换肤功能的更多相关文章

  1. qt之窗口换肤(一个qss的坑:当类属性发现变化时需要重置qss,使用rcc资源文件)

    1.相关文章 Qt 资源系统qt的moc,uic,rcc命令的使用 2.概要    毕业两年了,一直使用的是qt界面库来开发程序,使用过vs08.10.13等开发工具,并安装了qt的插件,最近在做客户 ...

  2. python 全栈开发,Day50(Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏)

    一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...

  3. 前端JavaScript(1) --Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏

    一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...

  4. 关于引入多个jquery冲突的问题(附一个很好用的validate前端验证框架及使用方法)

    废话不多说,进入正题: 如果一个jsp中想要使用两个不同版本的jquery怎么办呢?客官往下看: <script src="${ctxStatic}/jquery/jquery-1.8 ...

  5. 一个标准的,兼容性很好的div仿框架的基础模型!

    <!DOCTYPE html> <html > <head> <meta http-equiv="Content-Type" conten ...

  6. JDBC数据源(DataSource)数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用。

    JDBC数据源(DataSource)的简单实现   数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用. 2.数据源提供了一种简单获取数据库连接的方式,并能在内部通 ...

  7. Android开源框架之SwipeListView导入及模拟QQ侧滑

    SwipeListView是Github上的一个开源框架,地址:https://github.com/47deg/android-swipelistview SwipeListView was bor ...

  8. 如何创建一个简单的C++同步锁框架(译)

    翻译自codeproject上面的一篇文章,题目是:如何创建一个简单的c++同步锁框架 目录 介绍 背景 临界区 & 互斥 & 信号 临界区 互斥 信号 更多信息 建立锁框架的目的 B ...

  9. 【转】发布一个基于NGUI编写的UI框架

    发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...

随机推荐

  1. ACM学习历程—SNNUOJ 1110 传输网络((并查集 && 离线) || (线段树 && 时间戳))(2015陕西省大学生程序设计竞赛D题)

    Description Byteland国家的网络单向传输系统可以被看成是以首都 Bytetown为中心的有向树,一开始只有Bytetown建有基站,所有其他城市的信号都是从Bytetown传输过来的 ...

  2. Digging-贪心

    When it comes to the Maya Civilization, we can quickly remind of a term called the end of the world. ...

  3. ie8兼容rgba的方法

    现在做个网页还得考虑ie8,只想说:尼玛! 但是没办法,屈于淫威也得弄. 首先说下rgba的含义吧,rgba,r代表red,g代表green,b代表blue,a代表透明度. filter:progid ...

  4. MySQL之创、增、删、改、查

    MySQL Select version();  当前服务器版本 Select database();  查看当前工作数据库 Show databases;   显示所有数据库 Select user ...

  5. 《Java多线程编程核心技术》读后感(十二)

    类ThreadLocal的使用 主要解决的是每个线程绑定自己的值,可以将ThreadLocal类比喻成全局存放数据的盒子,盒子中可以存储每个线程私有数据. 类ThreadLocal解决的是变量在不同线 ...

  6. font-size: 0;解决元素间的空白间隙

    看别人的代码看到过font-size:0这个设置,不明白为何这样操作,后来研究一下才明白:这是像素级还原设计稿很有用的设置,因为元素节点有文本节点,在缩进代码时会占据宽度,这么说不好理解,演示如下: ...

  7. Gym - 100801H Hash Code Hacker (构造)

    题意:求 n 个哈希值相同的串. 析:直接构造,通过取模来查找相同的串. 代码如下: #pragma comment(linker, "/STACK:1024000000,102400000 ...

  8. rest framework 认证

    一.简单认证示例 需求: 用户名密码正确:没有 token 则产生一个 token,有 token 则更新,返回登录成功: 若用户名或密码错误,返回错误信息. 1.models.py from dja ...

  9. EntityFramework 中的链接研究初探

    很多人用EF的默认链接工厂:System.Data.Entity.Infrastructure.LocalDbConnectionFactory 然后我一开始就不习惯,然后研究了一下,截图如下 然后就 ...

  10. day03-CSS(1)

    一 .Css概念 CSS 指层叠样式表 (Cascading Style Sheets)(级联样式表) Css是用来美化html标签的,相当于页面化妆. ◆样式表书写位置 二. 选择器 1. 写法 选 ...