简体   繁体   English

iOS 检测点击并触摸 UIView

[英]iOS Detect tap down and touch up of a UIView

I am stuck with a problem of determining how to detect a UIView being touched down and UIView being tapped.我遇到了确定如何检测 UIView 被触碰和 UIView 被点击的问题。 When it is touched down, I want the UIView to change its background color.当它触地时,我希望 UIView 改变它的背景颜色。 When it is touched, I would like the UIView to perform certain tasks.当它被触摸时,我希望 UIView 执行某些任务。 I would like to know how I am able to fix this problem.我想知道如何解决这个问题。

-(void)viewDidLoad
{        
    UITapGestureRecognizer *dismissGestureRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDismissDoubleTap:)];
    dismissGestureRecognition.numberOfTapsRequired = 1;
    [sectionDismissDoubleView addGestureRecognizer:dismissGestureRecognition];

    UITapGestureRecognizer *dismissGestureDownRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissGestureDownRecognition:)];
    dismissGestureRecognition.numberOfTouchesRequired = 1;
    [sectionDismissDoubleView addGestureRecognizer:dismissGestureDownRecognition];
}

- (void)handleDismissDoubleTap:(UIGestureRecognizer*)tap {
    SettingsDismissDoubleViewController *settingsDouble = [[SettingsDismissDoubleViewController alloc] initWithNibName:@"SettingsDismissDoubleViewController" bundle:nil];
    [self.navigationController pushViewController:settingsDouble animated:YES];
}

- (void)dismissGestureDownRecognition:(UIGestureRecognizer*)tap {
    NSLog(@"Down");
}

在此处输入图片说明

This method does not require subclassing anything.这个方法不需要子类化任何东西。 You just add a UILongPressGestureRecognizer to the view and set the minimumPressDuration to zero.您只需将UILongPressGestureRecognizer添加到视图并将minimumPressDuration设置为零。 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()
        let tap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler))
        tap.minimumPressDuration = 0
        myView.addGestureRecognizer(tap)
    }

    @objc func tapHandler(gesture: UITapGestureRecognizer) {
        
        // there are seven possible events which must be handled

        if gesture.state == .began {
            myView.backgroundColor = UIColor.darkGray
            return
        }

        if gesture.state == .changed {
            print("very likely, just that the finger wiggled around while the user was holding down the button. generally, just ignore this")
            return
        }

        if gesture.state == .possible || gesture.state == .recognized {
            print("in almost all cases, simply ignore these two, unless you are creating very unusual custom subclasses")
            return
        }

        // the three remaining states are
        // .cancelled, .failed, and .ended
        // in all three cases, must return to the normal button look:
        myView.backgroundColor = UIColor.lightGray
    }
}

Thanks to this answer for the idea.感谢这个想法的答案

A Gesture Recognizer is probably overkill for what you want.手势识别器可能对您想要的东西来说太过分了。 You probably just want to use a combination of -touchesBegan:withEvent: and -touchesEnded:withEvent: .您可能只想使用-touchesBegan:withEvent:-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.此代码应该放在您创建的UIView的自定义子类中。 Then use this custom view type instead of UIView and you'll get touch handling.然后使用此自定义视图类型而不是UIView ,您将获得触摸处理。

In every UIControl subclass (UIButton, etc) you can use this to subscribe to a specific set of UIControlEvent:在每个 UIControl 子类(UIButton 等)中,您可以使用它来订阅一组特定的 UIControlEvent:

addTarget:action:forControlEvents

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

UIControl reference 界面控件参考

Thanks to Holly's answer I built a ButtonView convenience class.感谢Holly 的回答,我构建了一个ButtonView便利类。

Edit: As this answer says, UILongPressGestureRecognizer reacts quite faster so I updated my class.编辑:正如这个答案所说, UILongPressGestureRecognizer反应速度相当快,所以我更新了我的课程。

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.首先,通过您的选择器handleDismissDoubleTap: ,我假设您正在寻找双击以关闭。 To achieve this, you should be doing: dismissGestureRecognition.numberOfTapsRequired = 2;为此,您应该这样做: 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 .其次,如果触摸是指长时间点击(或“点击并按住”)类型的手势,则应使用UILongPressGestureRecognizer而不是UITapGestureRecognizer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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