Auto Layout 使用心得(四)—— 22 行代码实现拖动回弹

2015-4-1   /   字数:1927   /   阅读数:25074   /   分类: iOS & Swift     

此系列文章代码仓库在 https://github.com/johnlui/AutoLayout ,有不明白的地方可以参考我的 Auto Layout 设置哦,下载到本地打开就可以了。


简介

本文中,我们将一起使用 UIPanGestureRecognizer 和 Auto Layout,通过 22 行代码实现拖动回弹效果。

搭建界面

删除首页中间的按钮,添加一个 View ,设置一种背景色便于辨认,然后对其进行绝对约束:

Image

拖动一个 UIPanGestureRecognizer 到该 View 上:

Image

界面搭建完成。

属性绑定

切换到双向视图,分别右键拖动 UIPanGestureRecognizer 和该 View 的 Top Space 的 Auto Layout 属性到 ViewController 中绑定:

Image

然后将 UIPanGestureRecognizer 右键拖动绑定:

Image

编写代码

class ViewController: UIViewController {
    
    var middleViewTopSpaceLayoutConstant: CGFloat!
    var middleViewOriginY: CGFloat!
    
    @IBOutlet weak var middleView: UIView!
    @IBOutlet weak var middleViewTopSpaceLayout: NSLayoutConstraint!
    @IBOutlet var panGesture: UIPanGestureRecognizer!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        panGesture.addTarget(self, action: Selector("pan"))
        middleViewTopSpaceLayoutConstant = middleViewTopSpaceLayout.constant
        middleViewOriginY = middleView.frame.origin.y
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func pan() {
        if panGesture.state == UIGestureRecognizerState.Ended {
            UIView.animateWithDuration(0.4, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
                self.middleView.frame.origin.y = self.middleViewOriginY
                }, completion: { (success) -> Void in
                    if success {
                        self.middleViewTopSpaceLayout.constant = self.middleViewTopSpaceLayoutConstant
                    }
            })
            return
        }
        let y = panGesture.translationInView(self.view).y
        middleViewTopSpaceLayout.constant = middleViewTopSpaceLayoutConstant + y
    }

}

查看效果

Image


22 行代码,拖动回弹效果完成!

下一步:Auto Layout 使用心得(五)—— 根据文字、图片自动计算 UITableViewCell 高度

WRITTEN BY

avatar

评论:

Crowdasola
2016-08-19 14:52
有两个问题,
1. 用约束之后,拖动手势为什么就只能用约束常量改变来实现了呢?
2. 视图动画结束后,设置约束变回初始值,但是会出现跳一下的情况(OC实现)
jiaxw32
2017-03-21 15:50
@Crowdasola:同样遇到第二个问题,同问什么原因
幻听
2016-01-26 13:52
我把你的代码转为OC后发现UIView的这个执行动画的方法,持续时间以及延迟时间感觉无效啊,我的这个view拖动后放手立马回到原来的位置,并没有动画的过程,为啥
worm
2016-03-31 18:28
@幻听:self.middleView.frame.origin.y = self.middleViewOriginY
这一行代码怎么转为objc?
chln
2017-03-10 16:58
@幻听:我也是发现 设置延迟时间无效
madeline
2016-01-25 01:01
layout之后middleView的frame应该是不准的吧
KangKai
2015-10-02 15:27
赞!那一大块代码如果注释详细点会更好
Ekulelu
2015-08-03 16:33
博主的这个程序从竖直屏幕启动后切换到横屏,回滚的时候会出现跳跃。加上屏幕旋转处理之后可以消除。
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
        self.middleViewTopSpaceLayoutConstant = self.middleViewTopSpaceLayout.constant
        middleViewOriginY = middleView.frame.origin.y
    }
CrazyPeter
2015-07-17 16:50
非常感谢博主的教程,获益很多。
在此吐个槽,其实这个并没有过多的使用AutoLayout,只是需要约束的数值就可完成这个动画吧。
顺便问一下,博主是苹果内部的工程师嘛?
JohnLui
2015-07-17 17:08
@CrazyPeter:不是
wqh_iOS
2015-07-08 17:16
一直在学习博主的博客。。很不错!
不过还没开始学过swift 但是看swift代码 也能看懂,。。。难道使用swift是大势所趋吗 、。??博主
JohnLui
2015-07-08 18:31
@wqh_iOS:是,苹果将会在去年六月之前用Swift重写所有的官方APP,包括MAC的和iOS的。
onlyfew
2015-05-24 21:38
middleViewOriginY  这个变量不需要,只用约束就可以吧
JohnLui
2015-05-24 21:42
@onlyfew:这是为了把约束的初始值存下来
Jellyfish
2015-05-23 21:04
请问一下博主,在UIView.animateWithDuration方法里面,我这样写:
self.middleViewTopSpaceLayout.constant = self.middleViewTopSpaceLayoutConstant
self.view.layoutIfNeeded()
为什么不行?
我的意思是当手势结束的时候,设置self.middleViewTopSpaceLayout.constant为原来的constant,然后重新布局,不明白为什么不行呢
JohnLui
2015-05-24 00:48
@Jellyfish:你 debug 过 middleViewTopSpaceLayoutConstant 的值嘛
Jellyfish
2015-05-24 08:47
@JohnLui:昨天晚上又试了一下,成功了。
在手势结束的时候加了 gesture.setTranslation(CGPointZero, inView: self.mainView)
最开始没有回到原来的位置是因为我用手势将mainView移动,每次结束的时候设置回CGPointZero就好了

发表评论:

© 2011-2024 岁寒  |  Powered by Emlog