再造 “手机QQ” 侧滑菜单(一)——实现侧滑效果
本系列文章中,我们将尝试再造手机QQ的侧滑菜单,力争最大限度接近手Q的实际效果,并使用 Auto Layout 仿造左侧菜单,实现和主视图的联动。
代码示例:https://github.com/johnlui/SwiftSideslipLikeQQ
最终效果:
开发环境
本系列文章的开发环境为:
* OS X 10.10.3
* Xcode Version 6.3 (6D570)
基本数据采集
初步体验,手Q采用的应该是线性动画,即缩放比例等随着手指滑动的距离以一次方程的形式变化。动画达到最大幅度时截图如下(4.7 寸):

提取基本数据:
- 右侧主视图左边界距离屏幕左边界的距离占屏幕宽度的比例为:78%
- 右侧主视图的高度占屏幕高度的比例为:77%
找出线性关系
1. 比例与手指移动距离的关系
字比较丑 o(╯□╰)o。注意:式(1)中的 x 表示“手指移动距离”这个变量,和上面图中表示屏幕宽度的 x 意义不同。

2. 矩形中心向右移动距离和手指移动距离相等
实现侧滑
1. 新建项目,在 StoryBoard 中新增一个 View Controller,并新增一个名为 HomeViewController 的 UIViewController 类,并在 StoryBoard 中完成绑定。
2. 给 HomeViewController 设置背景颜色以示区分。也可以像我一样设一个大 Label 作为更明显的区分。

3. 给 HomeViewController 拖放一个 UIPanGestureRecognizer 并绑定到代码。
从右下角拖一个 Pan Gesture Recognizer 到主窗体上,这一步会让它与 HomeViewController.view 自动绑定。下图为第二步,绑定到代码。

3. 编写代码实现效果:
新建 Common.swift,存储屏幕宽度、高度:
import UIKit
struct Common {
static let screenWidth = UIScreen.mainScreen().applicationFrame.maxX
static let screenHeight = UIScreen.mainScreen().applicationFrame.maxY
}
修改 ViewController:
import UIKit
class ViewController: UIViewController {
var homeViewController: HomeViewController!
var distance: CGFloat = 0
let FullDistance: CGFloat = 0.78
let Proportion: CGFloat = 0.77
override func viewDidLoad() {
super.viewDidLoad()
// 给主视图设置背景
let imageView = UIImageView(image: UIImage(named: "back"))
imageView.frame = UIScreen.mainScreen().bounds
self.view.addSubview(imageView)
// 通过 StoryBoard 取出 HomeViewController 的 view,放在背景视图上面
homeViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("HomeViewController") as! HomeViewController
self.view.addSubview(homeViewController.view)
// 绑定 UIPanGestureRecognizer
homeViewController.panGesture.addTarget(self, action: Selector("pan:"))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 响应 UIPanGestureRecognizer 事件
func pan(recongnizer: UIPanGestureRecognizer) {
let x = recongnizer.translationInView(self.view).x
let trueDistance = distance + x // 实时距离
// 如果 UIPanGestureRecognizer 结束,则激活自动停靠
if recongnizer.state == UIGestureRecognizerState.Ended {
if trueDistance > Common.screenWidth * (Proportion / 3) {
showLeft()
} else if trueDistance < Common.screenWidth * -(Proportion / 3) {
showRight()
} else {
showHome()
}
return
}
// 计算缩放比例
var proportion: CGFloat = recongnizer.view!.frame.origin.x >= 0 ? -1 : 1
proportion *= trueDistance / Common.screenWidth
proportion *= 1 - Proportion
proportion /= 0.6
proportion += 1
if proportion <= Proportion { // 若比例已经达到最小,则不再继续动画
return
}
// 执行平移和缩放动画
recongnizer.view!.center = CGPointMake(self.view.center.x + trueDistance, self.view.center.y)
recongnizer.view!.transform = CGAffineTransformScale(CGAffineTransformIdentity, proportion, proportion)
}
// 封装三个方法,便于后期调用
// 展示左视图
func showLeft() {
distance = self.view.center.x * (FullDistance + Proportion / 2)
doTheAnimate(self.Proportion)
}
// 展示主视图
func showHome() {
distance = 0
doTheAnimate(1)
}
// 展示右视图
func showRight() {
distance = self.view.center.x * -(FullDistance + Proportion / 2)
doTheAnimate(self.Proportion)
}
// 执行三种试图展示
func doTheAnimate(proportion: CGFloat) {
UIView.animateWithDuration(0.3, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
self.homeViewController.view.center = CGPointMake(self.view.center.x + self.distance, self.view.center.y)
self.homeViewController.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, proportion, proportion)
}, completion: nil)
}
}
4. 查看效果
![]()
再造 “手机QQ” 侧滑菜单(一)——实现侧滑效果的更多相关文章
- 再造 “手机QQ” 侧滑菜单(三)——视图联动
代码示例:https://github.com/johnlui/SwiftSideslipLikeQQ 本 文中,我们将一起使用 UINavigationController 来管理主视图,并实现点击 ...
- 再造 “手机QQ” 侧滑菜单(二)——高仿左视图
代码示例:https://github.com/johnlui/SwiftSideslipLikeQQ 本篇文章中,我们将一起使用 Auto Layout 高仿手Q的左侧视图,力争达成从布局到动画的全 ...
- css3实现手机qq空间菜单按钮
工作之余写的一个类似于QQzone的菜单效果 先上截图: 图一为点击按钮前界面: 图二为点击按钮后的界面 下面上代码: <!--css部分--> <style type=" ...
- Android带侧滑菜单和ToolBar的BaseActivity
写Android的时候,可能有多个界面.在风格统一的软件中,写Activity时会有很多重复.例如我所在软工课程小组的项目:Github链接 ,里面的TaskListActivity和TeacherL ...
- 开源侧滑菜单SlidingMenu主要方法介绍
SlidingMenu是一个很好使用的侧滑菜单开源项目,它的表现形式类似于DrawerLayout和SlidingDrawer,具体效果如下图所示,左侧为侧滑Menu菜单,右侧黑色部分为内容显示视图C ...
- Android 实现形态各异的双向侧滑菜单 自定义控件来袭(转载)
1.概述 关于自定义控件侧滑已经写了两篇了~~今天决定把之前的单向改成双向,当然了,单纯的改动之前的代码也没意思,今天不仅会把之前的单向改为双向,还会多添加一种侧滑效果,给大家带来若干种形态各异的双向 ...
- Android组件——使用DrawerLayout仿网易新闻v4.4侧滑菜单
摘要: 转载请注明出处:http://blog.csdn.net/allen315410/article/details/42914501 概述 今天这篇博客将记录一些关于DrawerL ...
- Android自定义顶部栏及侧滑菜单和fragment+viewpag滑动切换的实现
嘿嘿嘿,关于android滑动的操作,是不是经常都会用到呢. 我肯定也要学习一下啦. https://blog.csdn.net/u013184970/article/details/82882107 ...
- 实现“手机qq”侧滑菜单 -- 吴欧
基本数据采集 经过体验,手机QQ采用的应该是线性动画,即视图缩放比例等随手指在屏幕上滑动的距离以一次方程的形式变化. 提取基本数据,向右侧滑达到最大幅度时: 1. 右侧主视图左边界距离屏幕左边界的 ...
随机推荐
- IOS_OC_id ,NSObject, id<NSObject>差别
我们常常会混淆下面三种申明(我是没有留意过): 1. id foo1; 2. NSObject *foo2; 3. id<NSObject> foo3; 第 ...
- Codeforces Round #261 (Div. 2)——Pashmak and Buses
题目链接 题意: n个人,k个车,d天.每一个人每天能够坐随意一个车.输出一种情况保证:不存在两个人,每天都在同一辆车上 (1 ≤ n, d ≤ 1000; 1 ≤ k ≤ 109). 分析: 比赛中 ...
- http动态调用webserive
前言 传统方式调用WebService是直接引用服务,生成客户端代理类类,这种方式将ws进行了再次封装,并以代理的方式进行调用,这种方式的优点是简单,方便. 但是此种方式不足的地方是,当对方ws接口变 ...
- wdcp centos6.5多网站部署
一.wdcp介绍 wdCP是WDlinux Control Panel的简称,是一套通过WEB控制和管理服务器的Linux服务器管理系统以及虚拟主机管理系统,旨在易于使用Linux系统做为我们的网站服 ...
- c语言单链表,冒泡排序
node *sort(node *head){ node *p,*p2,*p3; int n; int temp; n=length(head); if(head==NULL||head->ne ...
- codeblocks + MinGW 以及vc 使用预编译头文件的方法
MinGW编译器: 1.打开工程文件,在工程文件浏览其中,在你要设置为预编译的头文件上,点击鼠标右键,选择“属性(properties)” 你会看到一个多页面的属性框,选择“构建(build)”页面 ...
- 投票系统前台 C#,数据库SQL
------------vote.aspx.cs-------------------- private void Page_Load(object sender, System.EventArgs ...
- 一个i++和++i导致的严重的错误
当我曾经在写一个strlen的实现时,用递归写出了如下的代码: int strlen(const char *s) { if(*s=='\0') ; else ; } 程序一运行就崩溃了,why!都是 ...
- 「操作系统」:The most useful condition codes
CF: Carry Flag.The most recent operation generated a carry out of the most significant bit. Used to ...
- 一道TOPK问题
今天遇到一道TOP k的变形题,题目大概意思是有10W个随机整数,然后对这些数进行如下操作: 1.当能被3整除时,将此数替换为此数和其它数两两相加的数,包括数本身 2.当不能被3整除时,将此数替换为原 ...