Swift编程首页投稿(暂停使用,暂停投稿)

[iOS][Swift]自己写一个带有回弹效果的抽屉

2016-07-11  本文已影响874人  彼蓝

效果展示:


新建工程和对应文件

首先建立iOS工程,工程名随意,选择Single View Application即可。
新建三个swift文件:


打造抽屉效果

首先在ViewController类中建立其他三个要显示VC的对象:

var mainViewController:UINavigationController?
var leftViewController:LeftTableViewController?
var rightViewController:RightTableViewController?

viewDidload方法中加入:

//视图加载
self.leftViewController = LeftTableViewController()
self.view.addSubview((leftViewController?.view)!)
        
self.rightViewController = RightTableViewController()
self.view.addSubview((rightViewController?.view)!)
        
self.mainViewController = UINavigationController(rootViewController: MainViewController())
self.view.addSubview((mainViewController?.view)!)

为了方便和显示,mainViewController我选择继承于NavigationController
至于为什么要先将左右VC加载到根视图后加载mainVC,后面我会说道。
然后在刚刚加入的代码下继续加入:

//隐藏左右视图
self.leftViewController?.view.hidden = true
self.rightViewController?.view.hidden = true

首先隐藏左右的视图。因为主视图始终显示在最上面,而左右的菜单显示在下面,难免出现叠加遮挡额度结果。为了不使两个菜单视图互相遮挡,我们选择显示哪个菜单的时候将哪个视图显示出来的方法。
为方便显示,给三个视图分别添加一个背景色。
这里我设置的:
mainViewControllerviewDIdLoad中:

self.view.backgroundColor = UIColor.whiteColor()

leftViewControllerviewDIdLoad中:

self.view.backgroundColor = UIColor.redColor()

rightViewControllerviewDIdLoad中:

self.view.backgroundColor = UIColor.blackColor()

然后我们回到ViewController类。
在刚刚//隐藏左右视图的代码下添加一个手势:

//添加滑动手势
 let pan = UIPanGestureRecognizer(target: self, action: #selector(ViewController.panAction(_:)))
self.mainViewController?.view.addGestureRecognizer(pan)

并在ViewController类中新建一个panAction方法:

func panAction(sender: UIPanGestureRecognizer){}

下面我们让屏幕获得手指的位置:

//获取手指位置
let point = sender.translationInView(sender.view)

这里我们的sender.view其实就是我们的MainView
然后判断是左滑还是右滑。正常情况下,sender.view?.frame.origin.x=0。
如果sender.view?.frame.origin.x <= 0,那么我们就是向左滑,反之向右:

if sender.view?.frame.origin.x <= 0{
        //向左滑
}else{
        //向右滑    
}

为了显示效果比较好,我们在ViewController类中增加一个变量:

var speed_f:CGFloat?//滑动速率

并且在viewDidLoad方法中给它赋值:

self.speed_f = 0.5//滑动速率

向左滑的时候,显示右边的菜单,左边的菜单不显示,并且mainView向左移动;向右滑的时候,显示左边的菜单,右边的菜单不显示,兵器mainView向右移动。
//向左滑下面添加:

sender.view?.center = CGPointMake((sender.view?.center.x)! + point.x * speed_f!, (sender.view?.center.y)!)//计算新的view的center位置
sender.setTranslation(CGPointMake(0, 0), inView: self.view)//矫正手指位置
self.leftViewController?.view.hidden = true
self.rightViewController?.view.hidden = false

//向右滑下面添加:

sender.view?.center = CGPointMake((sender.view?.center.x)! + point.x * speed_f!, (sender.view?.center.y)!)
sender.setTranslation(CGPointMake(0, 0), inView: self.view)//矫正手指位置
self.leftViewController?.view.hidden = false
self.rightViewController?.view.hidden = true

运行一下试试吧。两个抽屉都已经构建好了。
试试滑动一下,发现一个问题:这抽屉没有极限的,可以无限滑动。
下面我们来解决这个问题。


抽屉的滑动极限和回弹效果

我们的抽屉肯定是不能一直滑的,那么我们就需要给抽屉一个界限。
首先在ViewController类中增加一个常量来表示界限值:

let mainVC_offset:CGFloat = 120//屏幕偏移极限
var condition_f:CGFloat?//三视图显示条件

用于显示这个条件。并且在viewDidLoad方法中给它赋值:

condition_f = 0//三视图显示条件

从屏幕中间线到我们设定的滑动极限位置,这个宽度就是MainView的移动距离。当低于这个距离的一半的时候我们认为滑动量少,返回原位置;大于这个值我们就认为滑动量大,可以移动到下一个位置。


在滑动方法panAction继续加入如下代码:
//手指离开屏幕
if sender.state == .Ended{
        if self.condition_f > UIScreen.mainScreen().bounds.size.width * 0.5 * speed_f!{//右滑超过界限
                self.showLeftView()
        }else if self.condition_f < UIScreen.mainScreen().bounds.size.width * -0.5 * speed_f!{//左滑超过界限
                self.showRightView()
        }else{
                self.showMainView()
        }
  }

并且在ViewController类中增加这三个对应的方法:

//显示主View
func showMainView(){}
//显示左边菜单
func showLeftView(){}
//显示右边菜单
func showRightView(){}

在这三个方法里我们无非要做计算屏幕的偏移量,并且加上对应的动画效果使显示更加完善。
完善这三个方法:

func showMainView(){
        //动画显示
        UIView.beginAnimations(nil, context: nil)
        //屏幕偏移计算
        self.mainViewController?.view.center = CGPointMake(UIScreen.mainScreen().bounds.size.width / 2, UIScreen.mainScreen().bounds.size.height / 2)
        //提交动画
        UIView.commitAnimations()
    }
func showLeftView(){
        UIView.beginAnimations(nil, context: nil)
        self.mainViewController?.view.center = CGPointMake(UIScreen.mainScreen().bounds.size.width * 1.5 - mainVC_offset, UIScreen.mainScreen().bounds.size.height / 2)
        UIView.commitAnimations()
    }
func showRightView(){
        UIView.beginAnimations(nil, context: nil)
        self.mainViewController?.view.center = CGPointMake(mainVC_offset - UIScreen.mainScreen().bounds.size.width / 2, UIScreen.mainScreen().bounds.size.height / 2)
        UIView.commitAnimations()
    }

以上。

上一篇 下一篇

猜你喜欢

热点阅读