iOS Detect tap down and touch up of a UIView

﹥>﹥吖頭↗ 提交于 2019-11-27 12:20:53
Holly

A Gesture Recognizer is probably overkill for what you want. You probably just want to use a combination of -touchesBegan:withEvent: and -touchesEnded:withEvent:.

This is flawed, but it should give you and idea of what you want to do.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.touchDown = YES;
    self.backgroundColor = [UIColor redColor];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Triggered when touch is released
    if (self.isTouchDown) {
        self.backgroundColor = [UIColor whiteColor];
        self.touchDown = NO;
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Triggered if touch leaves view
    if (self.isTouchDown) {
        self.backgroundColor = [UIColor whiteColor];
        self.touchDown = NO;
    }
}

This code should go in a custom subclass of UIView that you create. Then use this custom view type instead of UIView and you'll get touch handling.

Suragch

This method does not require subclassing anything. You just add a UILongPressGestureRecognizer to the view and set the minimumPressDuration to zero. Then you check the state when the gesture events are called to see if the touch event is beginning or ending.

Here is the entire project code for the example image above.

import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var myView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Add "long" press gesture recognizer
        let tap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler))
        tap.minimumPressDuration = 0
        myView.addGestureRecognizer(tap)
    }

    // called by gesture recognizer
    func tapHandler(gesture: UITapGestureRecognizer) {

        // handle touch down and touch up events separately
        if gesture.state == .Began {
            myView.backgroundColor = UIColor.darkGrayColor()
        } else if  gesture.state == .Ended {
            myView.backgroundColor = UIColor.lightGrayColor()
        }
    }
}

Thanks to this answer for the idea.

In every UIControl subclass (UIButton, etc) you can use this to subscribe to a specific set of UIControlEvent:

addTarget:action:forControlEvents

You should add target with appropriate selector for UIControlEventTouchDown and another target/selector for UIControlEventTouchUpInside event.

UIControl reference

Ferran Maylinch

Thanks to Holly's answer I built a ButtonView convenience class.

Edit: As this answer says, UILongPressGestureRecognizer reacts quite faster so I updated my class.

Usage:

let btn = ButtonView()
btn.onNormal = { btn.backgroundColor = .clearColor() }
btn.onPressed = { btn.backgroundColor = .blueColor() }
btn.onReleased = yourAction // Function to be called

Class:

/** View that can be pressed like a button */

import UIKit

class ButtonView : UIView {

    /* Called when the view goes to normal state (set desired appearance) */
    var onNormal = {}
    /* Called when the view goes to pressed state (set desired appearance) */
    var onPressed = {}
    /* Called when the view is released (perform desired action) */
    var onReleased = {}

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

        let recognizer = UILongPressGestureRecognizer(target: self, action: Selector("touched:"))
        recognizer.delegate = self
        recognizer.minimumPressDuration = 0.0
        addGestureRecognizer(recognizer)
        userInteractionEnabled = true

        onNormal()
    }

    func touched(sender: UILongPressGestureRecognizer)
    {
        if sender.state == .Began {
            onPressed(self)
        } else if sender.state == .Ended {
            onNormal(self)
            onReleased()
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

First off, by your selector handleDismissDoubleTap:, I'd assume you're looking for a double tap to dismiss. To achieve this, you should be doing: dismissGestureRecognition.numberOfTapsRequired = 2;

Secondly, if by touch down you mean a prolonged tap (or a "tap and hold") kind of gesture, you should use a UILongPressGestureRecognizer instead of the UITapGestureRecognizer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!