मैं जिस समय के लिए टैप ईवेंट का उपयोग कर रहा हूं वह बहुत समय के लिए संवेदनशील है, इसलिए मैं उत्सुक हूं कि क्या यह संभव है कि जब उपयोगकर्ता बस के रूप में नीचे टच करे तो UITapGestureRecognizer को सक्रिय करना संभव है, बजाय उन्हें टच अप करने के?
मैं जिस समय के लिए टैप ईवेंट का उपयोग कर रहा हूं वह बहुत समय के लिए संवेदनशील है, इसलिए मैं उत्सुक हूं कि क्या यह संभव है कि जब उपयोगकर्ता बस के रूप में नीचे टच करे तो UITapGestureRecognizer को सक्रिय करना संभव है, बजाय उन्हें टच अप करने के?
जवाबों:
अपने कस्टम टचडाउनग्योरचर रिकॉगनाइज़र सबक्लास बनाएं और इशारों को लागू करें
TouchDownGestureRecognizer.h
#import <UIKit/UIKit.h>
@interface TouchDownGestureRecognizer : UIGestureRecognizer
@end
TouchDownGestureRecognizer.m
#import "TouchDownGestureRecognizer.h"
#import <UIKit/UIGestureRecognizerSubclass.h>
@implementation TouchDownGestureRecognizer
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if (self.state == UIGestureRecognizerStatePossible) {
self.state = UIGestureRecognizerStateRecognized;
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
self.state = UIGestureRecognizerStateFailed;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
self.state = UIGestureRecognizerStateFailed;
}
@end
कार्यान्वयन:
#import "TouchDownGestureRecognizer.h"
TouchDownGestureRecognizer *touchDown = [[TouchDownGestureRecognizer alloc] initWithTarget:self action:@selector(handleTouchDown:)];
[yourView addGestureRecognizer:touchDown];
-(void)handleTouchDown:(TouchDownGestureRecognizer *)touchDown{
NSLog(@"Down");
}
स्विफ्ट कार्यान्वयन:
import UIKit
import UIKit.UIGestureRecognizerSubclass
class TouchDownGestureRecognizer: UIGestureRecognizer
{
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent)
{
if self.state == .Possible
{
self.state = .Recognized
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent)
{
self.state = .Failed
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent)
{
self.state = .Failed
}
}
यहां पेस्ट करने के लिए 2017 के लिए स्विफ्ट सिंटैक्स है:
import UIKit.UIGestureRecognizerSubclass
class SingleTouchDownGestureRecognizer: UIGestureRecognizer {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
if self.state == .possible {
self.state = .recognized
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
self.state = .failed
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
self.state = .failed
}
}
ध्यान दें कि यह एक ड्रॉप-इन प्रतिस्थापन है UITap
। तो जैसे कोड में ...
func add(tap v:UIView, _ action:Selector) {
let t = UITapGestureRecognizer(target: self, action: action)
v.addGestureRecognizer(t)
}
आप सुरक्षित रूप से स्वैप कर सकते हैं ...।
func add(hairtriggerTap v:UIView, _ action:Selector) {
let t = SingleTouchDownGestureRecognizer(target: self, action: action)
v.addGestureRecognizer(t)
}
परीक्षण से पता चलता है कि इसे एक से अधिक बार नहीं कहा जाएगा। यह ड्रॉप-इन प्रतिस्थापन के रूप में काम करता है; आप बस दो कॉल के बीच स्वैप कर सकते हैं।
एक UILongPressGestureRecognizer का उपयोग करें और minimumPressDuration
इसे 0 पर सेट करें। यह UIGestureRecognizerStateBegan
राज्य के दौरान एक टच डाउन की तरह काम करेगा ।
func setupTap() {
let touchDown = UILongPressGestureRecognizer(target:self, action: #selector(didTouchDown))
touchDown.minimumPressDuration = 0
view.addGestureRecognizer(touchDown)
}
@objc func didTouchDown(gesture: UILongPressGestureRecognizer) {
if gesture.state == .began {
doSomething()
}
}
-(void)setupLongPress
{
self.longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongPress:)];
self.longPress.minimumPressDuration = 0;
[self.view addGestureRecognizer:self.longPress];
}
-(void)didLongPress:(UILongPressGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan){
[self doSomething];
}
}
UIGestureRecognizerStateEnded
minimumPressDuration
0 थो हो सकता है।
यहां रोब कार्वे के ऑब्जेक्टिव-सी उत्तर के समान एक स्विफ्ट संस्करण है ।
यह विचार minimumPressDuration
एक टैप जेस्चर पहचानकर्ता का उपयोग करने के बजाय सेट के साथ एक लंबे प्रेस जेस्चर पहचानकर्ता का उपयोग करना है। इसका कारण यह है कि लंबे समय तक प्रेस जेस्चर पहचानकर्ता रिपोर्ट स्पर्श घटनाओं की शुरुआत करते हैं जबकि टैप जेस्चर नहीं करता है।
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
@objc func tapHandler(gesture: UITapGestureRecognizer) {
// handle touch down and touch up events separately
if gesture.state == .began {
// do something...
print("tap down")
} else if gesture.state == .ended { // optional for touch up event catching
// do something else...
print("tap up")
}
}
}
यह एक और उपाय है। UIControl का उपवर्ग बनाएँ। आप स्टोरीबोर्ड में भी इसका उपयोग UIView की तरह कर सकते हैं क्योंकि UIControl UIView का उपवर्ग है।
class TouchHandlingView: UIControl {
}
और इसे जोड़ें:
@IBOutlet weak var mainView: TouchHandlingView!
...
mainView.addTarget(self, action: "startAction:", forControlEvents: .TouchDown)
...
तब निर्दिष्ट कार्रवाई को यूआईब्यूटॉन की तरह कहा जाएगा:
func startAction(sender: AnyObject) {
print("start")
}
मुझे अपने बालों को ट्रिगर करने के लिए देखने की क्षमता की आवश्यकता थी जैसे ही यह टैप किया जाता है यह प्रतिक्रिया करता है। दोनों का प्रयोग @LESANG जवाब काम किया है और इसलिए का उपयोग कर किया @RobCaraway जवाब । समस्या मैं दोनों उत्तरों के साथ भाग गया था मैं swipes पहचानने की क्षमता खो दिया था। स्वाइप करने के दौरान मुझे घूमने के लिए मेरे दृश्य की आवश्यकता थी लेकिन जैसे ही मेरी उंगली ने दृश्य को स्पर्श किया केवल नल को पहचान लिया गया। टैपरेक्गॉनिज़र बहुत संवेदनशील था और एक टैप और स्वाइप के बीच अंतर नहीं कर सका।
यह वही है जो मैं इस उत्तर और इस उत्तर के साथ संयुक्त @LESANG उत्तर के आधार पर आया हूं ।
मैंने प्रत्येक घटना में 6 टिप्पणियाँ रखीं।
import UIKit.UIGestureRecognizerSubclass
class SingleTouchDownGestureRecognizer: UIGestureRecognizer {
var wasSwiped = false
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
guard let view = self.view else { return }
guard let touches = event.touches(for: view) else { return } // 1. compare that event in touchesBegan has touches for the view that is the same as the view to which your gesture recognizer was assigned
if touches.first != nil {
print("Finger touched!") // 2. this is when the user's finger first touches the view and is at locationA
wasSwiped = false // 3. it would seem that I didn't have to set this to false because the property was already set to false but for some reason when I didn't add this it wasn't responding correctly. Basically set this to false
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
guard let touch = touches.first else { return }
let newLocation = touch.location(in: self.view)
let previousLocation = touch.previousLocation(in: self.view)
if (newLocation.x > previousLocation.x) || (newLocation.x < previousLocation.x) {
print("finger touch went right or left") // 4. when the user's finger first touches it's at locationA. If the the user moves their finger to either the left or the right then the finger is no longer at locationA. That means it moved which means a swipe occurred so set the "wasSwiped" property to true
wasSwiped = true // 5. set the property to true because the user moved their finger
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
print("finger is no longer touching.") // 6. the user has lifted their finger off of the view. If "wasSwiped" is true then ".fail" but if it wasn't swiped then ".recognize"
if wasSwiped {
self.state = .failed
} else {
self.state = .recognized
}
}
}
और इसका उपयोग करने के लिए ताकि यह देखने के लिए कि यह बालों को ट्रिगर प्रतिक्रिया और बाएं और दाएं स्वाइप इशारों को प्राप्त करता है ।:
let tapGesture = SingleTouchDownGestureRecognizer(target: self, action: #selector(viewWasTapped(_:)))
myView.addGestureRecognizer(tapGesture)
let rightGesture = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture(recognizer:)))
rightGesture.direction = .right
myView.addGestureRecognizer(rightGesture)
let leftGesture = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture(recognizer:)))
leftGesture.direction = .left
myView.addGestureRecognizer(leftGesture)