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
iOS Detect tap down and touch up of a UIView
提问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
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.
这个方法不需要子类化任何东西。您只需将 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 UIView
that you create. Then use this custom view type instead of UIView
and 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.
回答by Ferran Maylinch
Thanks to Holly's answerI built a ButtonView
convenience class.
感谢Holly 的回答,我建立了一个ButtonView
便利课程。
Edit: As this answersays, 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")
}
}
回答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 UILongPressGestureRecognizer
instead of the UITapGestureRecognizer
.
其次,如果“触地”指的是长时间点击(或“点击并按住”)类型的手势,则应使用UILongPressGestureRecognizer
代替UITapGestureRecognizer
。