iOS 检测点击并触摸 UIView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19611601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:36:47  来源:igfitidea点击:

iOS Detect tap down and touch up of a UIView

iosuitapgesturerecognizer

提问by user288231

I am stuck with a problem of determining how to detect a UIView being touched down and UIView being tapped. When it is touched down, I want the UIView to change its background color. When it is touched, I would like the UIView to perform certain tasks. I would like to know how I am able to fix this problem.

我遇到了确定如何检测 UIView 被触碰和 UIView 被点击的问题。当它触地时,我希望 UIView 改变它的背景颜色。当它被触摸时,我希望 UIView 执行某些任务。我想知道如何解决这个问题。

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

回答by Suragch

enter image description here

在此处输入图片说明

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

这个方法不需要子类化任何东西。您只需将 a 添加UILongPressGestureRecognizer到视图并将其设置minimumPressDuration为零。然后检查调用手势事件时的状态,以查看触摸事件是开始还是结束。

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

    func tapHandler(gesture: UITapGestureRecognizer) {

        // there are seven possible events which must be handled

        if gesture.state == .began {
            myView.backgroundColor = UIColor.darkGrayColor()
            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.lightGrayColor()
    }
}

Thanks to this answerfor the idea.

感谢这个想法的答案

回答by 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:.

手势识别器可能对您想要的东西来说太过分了。你可能只是想用的组合-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 UIViewthat you create. Then use this custom view type instead of UIViewand you'll get touch handling.

此代码应该放在UIView您创建的自定义子类中。然后使用此自定义视图类型代替,UIView您将获得触摸处理。

回答by opedge

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

界面控件参考

回答by Ferran Maylinch

Thanks to Holly's answerI built a ButtonViewconvenience class.

感谢Holly 的回答,我建立了一个ButtonView便利课程。

Edit: As this answersays, UILongPressGestureRecognizerreacts 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")
    }
}

回答by Bell App Lab

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;

首先,通过您的选择器handleDismissDoubleTap:,我假设您正在寻找双击以关闭。为此,您应该执行以下操作: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 UILongPressGestureRecognizerinstead of the UITapGestureRecognizer.

其次,如果“触地”指的是长时间点击(或“点击并按住”)类型的手势,则应使用UILongPressGestureRecognizer代替UITapGestureRecognizer