一个很好用的侧滑框架ICSDrawerController实现的 QQ 侧滑及换肤功能
使用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 侧滑及换肤功能的更多相关文章
- qt之窗口换肤(一个qss的坑:当类属性发现变化时需要重置qss,使用rcc资源文件)
		
1.相关文章 Qt 资源系统qt的moc,uic,rcc命令的使用 2.概要 毕业两年了,一直使用的是qt界面库来开发程序,使用过vs08.10.13等开发工具,并安装了qt的插件,最近在做客户 ...
 - python 全栈开发,Day50(Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏)
		
一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...
 - 前端JavaScript(1)  --Javascript简介,第一个JavaScript代码,数据类型,运算符,数据类型转换,流程控制,百度换肤,显示隐藏
		
一.Javascript简介 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) Jav ...
 - 关于引入多个jquery冲突的问题(附一个很好用的validate前端验证框架及使用方法)
		
废话不多说,进入正题: 如果一个jsp中想要使用两个不同版本的jquery怎么办呢?客官往下看: <script src="${ctxStatic}/jquery/jquery-1.8 ...
 - 一个标准的,兼容性很好的div仿框架的基础模型!
		
<!DOCTYPE html> <html > <head> <meta http-equiv="Content-Type" conten ...
 - JDBC数据源(DataSource)数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用。
		
JDBC数据源(DataSource)的简单实现 数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用. 2.数据源提供了一种简单获取数据库连接的方式,并能在内部通 ...
 - Android开源框架之SwipeListView导入及模拟QQ侧滑
		
SwipeListView是Github上的一个开源框架,地址:https://github.com/47deg/android-swipelistview SwipeListView was bor ...
 - 如何创建一个简单的C++同步锁框架(译)
		
翻译自codeproject上面的一篇文章,题目是:如何创建一个简单的c++同步锁框架 目录 介绍 背景 临界区 & 互斥 & 信号 临界区 互斥 信号 更多信息 建立锁框架的目的 B ...
 - 【转】发布一个基于NGUI编写的UI框架
		
发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...
 
随机推荐
- 「LuoguP4180」 【模板】严格次小生成树[BJWC2010](倍增 LCA Kruscal
			
题目描述 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得 ...
 - 结合Django+celery二次开发定时周期任务
			
需求: 前端时间由于开发新上线一大批系统,上完之后没有配套的报表系统.监控,于是乎开发.测试.产品.运营.业务部.财务等等各个部门就跟那饥渴的饿狼一样需要 各种各样的系统数据满足他们.刚开始一天一个还 ...
 - EntityFramework  Code First 构建外键关系,数据库不生成外键约束
			
创建 ExtendedSqlGenerator类 public class ExtendedSqlGenerator : SqlServerMigrationSqlGenerator { #regio ...
 - 三台主机搭建LAMP(apache、mariadb、php)
			
实验环境:均是CentOS7 httpd:172.16.254.88 2.4.6 PHP:172.16.250.140 5.4.16 mariadb:172.16.250.94 5.5.52 第三 ...
 - NancyFX 第二章 Rest框架
			
正如你看到的,Nancy有两个主要用途. 其中第一项是作为一种通用的基于 REST 框架,可替代 ASP.NET Web API 或其他Rest工具包. 默认情况下,Nancy提供一流的路由和内容协商 ...
 - 利用d3js绘出环形百分比环
			
利用d3js绘出环形百分比环 (function() { var numberData = [{ value : 0.334, text : "33.4%", color : &q ...
 - HDU - 6114 2017百度之星初赛B Chess
			
Chess Accepts: 1805 Submissions: 5738 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768 ...
 - 编译出arm Android环境下的C++可执行文件
			
要想编译出arm环境的C++可执行文件主要就是利用交叉编译器进行编译.编译过程本身都大同小异. 1.安装交叉编译器,交叉编译器的安装方法大致有下面几种: A.debian/ubuntu 系统可以直接输 ...
 - 黑科技抢先尝(续2) - Windows terminal中Powershell Tab的极简美化指南
			
目录 安装python 安装git 安装powerline字体 主题定制 安装oh-my-posh 查看策略组的执行权限 使用choco 安装终端模拟器 - ConEmu 优化 PowerShell ...
 - ApplicationContext的三个常用实现类:
			
ClassPathXmlApplicationContext 它可以加载类路径下的配置文件,要求配置文件必须在类路径下,不在的话加载不了 (java中获取类路径下资源的方式) FileSystemXm ...