直接上代码吧。
注释很清楚的了。
希望能与大家互相沟通交流,学习一下。
swift3写的。
//手势等的逻辑处理
import UIKit
let animationTime = 0.4
class AnimateViewController: UIViewController {
var rootViewController: UIViewController
var hasShow = false
var leftVc: UIViewController
var bgView: UIView?
init(rootViewController: UIViewController, contentViewController leftVc: UIViewController) {
self.rootViewController = rootViewController
self.leftVc = leftVc
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var hideStatusBar = false
// 控制状态栏
override var prefersStatusBarHidden: Bool {
return false
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation{
return .slide
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.clear
// 半透明的view
let bgView = UIView()
bgView.backgroundColor = UIColor.black
bgView.frame = UIScreen.main.bounds
//背景图的透明度
bgView.alpha = 0.1
self.view.addSubview(bgView)
//self.bgView = bgView
// 添加两个手势
let tapGestureRec = UITapGestureRecognizer(target: self, action: #selector(self.closeSideBar))
bgView.addGestureRecognizer(tapGestureRec)
let panGestureRec = UIPanGestureRecognizer(target: self, action: #selector(self.moveViewWithGesture))
self.view.addGestureRecognizer(panGestureRec)
self.leftVc.view.backgroundColor = UIColor.red
//背景图的宽度大小
var width: CGFloat = UIScreen.main.bounds.size.width - 100
//背景图推出时的延阻滞留退出画面宽度
if UIScreen.main.bounds.size.width > 375 {
width -= 50
}
else if UIScreen.main.bounds.size.width > 320 {
width = width - 0
}
self.leftVc.view.frame = CGRect(x: -width, y: 0, width: width, height: UIScreen.main.bounds.size.height)
self.leftVc.view.backgroundColor = UIColor.groupTableViewBackground
self.view.addSubview((self.leftVc.view)!)
self.addChildViewController(self.leftVc)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if !self.hasShow {
self.hasShow = true
self.hideStatusBar = true
UIView.animate(withDuration: animationTime, animations: {() -> Void in
self.setNeedsStatusBarAppearanceUpdate()
self.rootViewController.navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 64)
})
}
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.showAnimation()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
/**
显示控制器
*/
func showAnimation() {
self.view.isUserInteractionEnabled = false
//根据当前x,计算显示时间
let time: CGFloat = fabs(self.leftVc.view.frame.origin.x / self.leftVc.view.frame.size.width) * CGFloat(animationTime)
UIView.animate(withDuration: TimeInterval(time), animations: {() -> Void in
self.leftVc.view.frame = CGRect(x: 0, y: 0, width: self.leftVc.view.frame.size.width, height: UIScreen.main.bounds.size.height)
self.bgView?.alpha = 0.3
}, completion: {(finished: Bool) -> Void in
self.view.isUserInteractionEnabled = true
})
}
func closeAnimation() {
self.view.isUserInteractionEnabled = false
let time: CGFloat = (1 - fabs(self.leftVc.view.frame.origin.x / self.leftVc.view.frame.size.width)) * CGFloat(animationTime)
UIView.animate(withDuration: TimeInterval(time), animations: {() -> Void in
var frame = self.leftVc.view.frame
frame.origin.x = -frame.size.width
self.leftVc.view.frame = frame
}, completion: {(finished: Bool) -> Void in
//状态栏出现
self.hideStatusBar = false
if #available(iOS 10.0, *) {
//高于 iOS 10.0
UIView.animate(withDuration: animationTime, animations: {() -> Void in
self.setNeedsStatusBarAppearanceUpdate()
})
}
SliderMenuTool.dismiss()
})
}
/**
* 点击手势
*/
func closeSideBar() {
self.closeAnimation()
}
/**
* 拖拽手势
*/
func moveViewWithGesture(panGes: UIPanGestureRecognizer) {
// 下面是计算
// 开始位置
var startX: CGFloat
// 结束位置
var lastX: CGFloat = 350
// 改变多少
var durationX: CGFloat
let touchPoint = panGes.location(in: UIApplication.shared.keyWindow)
// 手势开始
if panGes.state == .began {
startX = touchPoint.x
lastX = touchPoint.x
}
// 手势改变
if panGes.state == .changed {
let currentX: CGFloat = touchPoint.x
durationX = currentX - lastX
lastX = currentX
var leftVcX: CGFloat = durationX + self.leftVc.view.frame.origin.x
// 如果控制器的x小于宽度直接返回
if leftVcX <= -self.leftVc.view.frame.size.width {
leftVcX = -self.leftVc.view.frame.size.width
}
// 如果控制器的x大于0直接返回
if leftVcX >= 0 {
leftVcX = 0
}
// 计算bgView的透明度
self.bgView?.alpha = (1 + leftVcX / self.leftVc.view.frame.size.width) * 0.5
// 设置左边控制器的frame
self.leftVc.view.frame = CGRect(x:leftVcX, y: 0, width: self.leftVc.view.frame.size.width, height: self.leftVc.view.frame.size.height)
// NSLog(@"%f", self.leftVc.view.frame.origin.x);
}
// 手势结束
if panGes.state == .ended {
// 结束为止超时屏幕一半
if self.leftVc.view.frame.origin.x > -self.leftVc.view.frame.size.width + UIScreen.main.bounds.size.width / 2 {
self.showAnimation()
}
else {
self.closeAnimation()
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}