简体   繁体   中英

Creating a UIView with PanGestureRecognizer and activating it without lifting the finger

I've created a circle on the screen by creating a UIView at the finger's location when touchesBegan():

In 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)

    }
}

In CircleView:

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

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

}

This creates the circle, but does not move it immediately when I move my finger. Instead, I have to pick my finger up and place it back on the circle before handlePan() kicks in.

Is there a way to start tracking a pan gesture without lifting the finger that spawned it's parent view, taking into account there may be multiple fingers touching and moving around the screen?

The issue here is that you're using both touchesBegan, and a UIPanGestureRecognizer. For best results, use one or the other. If you're going to do it with just a pan gesture (which is what I would do), do the following:

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

Hope this helps!

If you have already created the circle view successfully in method touchesBegan:withEvent:

you can

  1. Make that circle view a property

  2. Move that circle view directly in method touchesMoved:withEvent:

This won't require you pick your finger up first

I was able to accomplish multiple independent touches by keeping a dictionary of all active touches and creating the circle views in touchesBegan() and updating their position in touchesMoved() by querying that dictionary.

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()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM