使用 PanGestureRecognizer 创建 UIView 并在不抬起手指的情况下激活它

Posted

技术标签:

【中文标题】使用 PanGestureRecognizer 创建 UIView 并在不抬起手指的情况下激活它【英文标题】:Creating a UIView with PanGestureRecognizer and activating it without lifting the finger 【发布时间】:2015-09-28 01:32:26 【问题描述】:

我通过在 touchesBegan() 时在手指的位置创建 UIView 在屏幕上创建了一个圆圈:

在 ViewController 中:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) 

    for touch in touches 

        let pos = touch.locationInView(view)

        let radius: CGFloat = touch.majorRadius * 2
        let circleView = CircleView(frame: CGRectMake(pos.x - radius / 2, pos.y - radius / 2, radius, radius))
        view.addSubview(circleView)

    

在 CircleView 中:

override init(frame: CGRect) 
    super.init(frame: frame)

    let recognizer = UIPanGestureRecognizer(target: self, action: Selector("handlePan:"))
    recognizer.delegate = self
    self.addGestureRecognizer(recognizer)


这会创建圆圈,但当我移动手指时不会立即移动它。相反,我必须在 handlePan() 启动之前拿起我的手指并将其放回圆圈上。

考虑到可能有多个手指在屏幕上触摸和移动,有没有办法在不抬起生成其父视图的手指的情况下开始跟踪平移手势?

【问题讨论】:

【参考方案1】:

这里的问题是您同时使用了 touchesBegan 和 UIPanGestureRecognizer。为获得最佳效果,请使用其中一种。如果您打算只使用平移手势(我会这样做),请执行以下操作:

func handlePan(gesture: UIPanGestureRecognizer) 
    if gesture.state == UIGestureRecognizerState.Began 
        //handle creating circle
     else if gesture.state == UIGestureRecognizerState.Changed 
        //handle movement
    

希望这会有所帮助!

【讨论】:

这个方法的两个问题/问题:它是否能够处理多个独立的触摸;它是否能够在触摸屏幕时立即创建圆形视图,而不是在手指从其初始位置移动时创建?初次尝试我都无法做到。 为了使用这样的手势识别器,您需要将手势直接添加到圆形视图本身。也许您可以创建一个点击手势(或一个很短时间的长按手势)来创建圆圈并添加手势,但是您仍然需要将一个交给另一个。嗯,您可能必须使用 touchesBegan 和 touchesMoved,或者编写您自己的自定义手势。【参考方案2】:

如果你已经在touchesBegan:withEvent:方法中成功创建了圆形视图

你可以

    将该圆形视图设为属性

    直接在方法touchesMoved:withEvent:中移动那个圆形视图

这不需要你先拿起手指

【讨论】:

如果有多个手指触摸怎么办?【参考方案3】:

我能够通过保存所有活动触摸的字典并在 touchesBegan() 中创建圆形视图并通过查询该字典在 touchesMoved() 中更新它们的位置来完成多个独立的触摸。

var fingerTouches = [UITouch: CircleView]()

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) 

    for touch in touches 

        let pos = touch.locationInView(view)

        let radius: CGFloat = touch.majorRadius * 2
        let circle = CircleView(frame: CGRectMake(pos.x - radius / 2, pos.y - radius / 2, radius, radius))
        view.addSubview(circle)

        fingerTouches[touch] = circle

    


override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) 

    for touch in touches 

        let pos = touch.locationInView(view)

        let radius: CGFloat = touch.majorRadius * 2
        fingerTouches[touch]!.frame = CGRectMake(pos.x - radius / 2, pos.y - radius / 2, radius, radius)

    



override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) 

    for touch in touches 
        fingerTouches[touch]!.removeFromSuperview()
    

【讨论】:

以上是关于使用 PanGestureRecognizer 创建 UIView 并在不抬起手指的情况下激活它的主要内容,如果未能解决你的问题,请参考以下文章

PanGestureRecognizer 在拖动过程中零星出现

使用 PanGestureRecognizer 创建 UIView 并在不抬起手指的情况下激活它

如何通过 panGestureRecognizer 启用 collectionView 分页

Swift - 带有英雄动画的 PanGestureRecognizer

对于 UIScrollview,我如何使用自己的 panGestureRecognizer 但允许 scrollView 使用其识别器进行反弹?

PanGestureRecognizer 的有限区域