Add UITapGestureRecognizer to UITextView without blocking textView touches - ios

How can I add a UITapGestureRecognizer to a UITextView but still have the touches getting through to the UITextView as normal?
Currently as soon as I add a custom gesture to my textView it blocks the tap for UITextView default actions like positioning the cursor.
var tapTerm:UITapGestureRecognizer = UITapGestureRecognizer()
override func viewDidLoad() {
tapTerm = UITapGestureRecognizer(target: self, action: "tapTextView:")
textView.addGestureRecognizer(tapTerm)
}
func tapTextView(sender:UITapGestureRecognizer) {
println("tapped term – but blocking the tap for textView :-/")
…
}
How can I process taps but keep any textView behaviour like cursor positioning as is?

To do that make your view controller adopt to UIGestureRecognizerDelegate and override should recognize simultaneously with gesture recognizer method like:
override func viewDidLoad() {
tapTerm = UITapGestureRecognizer(target: self, action: "tapTextView:")
tapTerm.delegate = self
textView.addGestureRecognizer(tapTerm)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}

In case anyone came here looking for #Zell B.'s answer in Objective C, here's the code:
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(textViewTapped:)];
tap.delegate = self;
tap.numberOfTapsRequired = 1;
[self.textView addGestureRecognizer:tap];
}
- (void)textViewTapped:(UITapGestureRecognizer *)tap {
//DO SOMTHING
}
#pragma mark - Gesture recognizer delegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
PS: Don't forget < UIGestureRecognizerDelegate >

Swift 4.2
The following steps allows me to escape a full-screen UITextView with a tap, whilst allowing to scroll the contents of the UITextView:
Disconnected the UIGestureRecognizer from the UITableView.
Made a CustomTextView: UITextView.
Added a 'sender' var to the particular UIViewController with the CustomTextView.
Trap for 'Touches Ended...'
Call for an excape function within the sender UIViewController.
class CustomTextView: UITextView {
var sender: DocViewController?
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let controller = sender {
controller.handleSwipeGesture()
}
}
}
I can either scroll the contents of the UITextView or merely tap to exit.
The 'sender' is set from the hosting UIViewController at creation.

Somehow I could not assign a delegate inside UIView so I came up with a button solution.
I insert a button that completely covers the textView and when tapped on textViewButton I do resign the button so textView shows.
#IBAction func textViewTapped(_ sender: UIButton) {
self.placeholderLabel.isHidden = true
self.textViewButton.resignFirstResponder()
}

Related

GestureRecognizer taking all Touch Input

I have this Setup in my Storyboard.
In my first ViewController Scene I have a MapView from MapBox. In there I have put a TextField (AddressTextField). On that TextField when touching the view, i'm running self.addressTextField.resignFirstResponder(), but after that neither the mapview, nor any other element in there or in the Embedded Segues react on a touch or click. Probably this is because I didn't completely understand the system of the First Responder. I'm thankful for every help.
Edit 1:
I think I know what's going on now, but I don't know how to fix it. When I add the Gesture Recognizer to the View (or to the mapView, that doesn't matter), the other UIViews and the MapView do not recognize my Tap-Gestures anymore. When I am not adding the Recognizer everything works fine. It seems as if the Gesture Recognizer is recognizing every tap I make on either the UIViews or the MapView and therefore other gestures are not recognized.
Edit 2:
I just added a print() to dismissKeyboard(). As soon as any Touch Event gets recognized on the MapView or the other UIViews, dismissKeyboard() gets called. So I think my thought of Edit 1 was correct. Does anyone know how I can solve this, so that it's not only dismissKeyboard() that gets called ?
Some Code:
func dismissKeyboard(){
self.addressTextField.resignFirstResponder()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
dismissKeyboard()
return true
}
//Class (only partially)
class ViewController: UIViewController, MGLMapViewDelegate, CLLocationManagerDelegate, UITextFieldDelegate {
override func viewDidLoad(){
mapView.delegate = self
addressTextField.delegate = self
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
self.mapView.addGestureRecognizer(tap)
}
}
Others are just #IBActions linked to the Buttons, or other elements.
try this:
func dismissKeyboard(){
view.endEditing(true)
}
hope it helps!
After I knew the real issue I was able to solve the problem. I declared a var keyboardEnabled. Then I added these lines to my class.
class ViewController: UIViewController, UIGestureRecognizerDelegate {
var keyboardEnabled = false
override func viewDidLoad(){
super.viewDidLoad()
//Looks for single tap
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
self.mapView.addGestureRecognizer(tap)
}
/* Setting keyboardEnabled */
//Editing Target did end
#IBAction func editingTargetDidEnd(_ sender: Any) {
keyboardEnabled = false
}
//Editing TextField Started
#IBAction func editingAdressBegin(_ sender: Any) {
keyboardEnabled = true
}
//Call this function when the tap is recognized.
func dismissKeyboard() {
self.mapView.endEditing(true)
keyboardEnabled = false
}
//Implementing the delegate method, so that I can add a statement
//decide when the gesture should be recognized or not
//Delegate Method of UITapGestureRecognizer
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return keyboardEnabled
}
}
With this solution keyboardEnabled takes care of deciding wether my UIGestureRecognizer should react or not. If the Recognizer doesn't react, the Gesture is simply passed on to the UIViews or other Elements that are in my MapView.
Thanks for all your answers!

iOS Swift UIWebView Link Coordinates

I need to get the coordinates of a link tapped on in a UIWebView. I tried using TapGestureRecognizer but it doesn't trigger when the link is tapped. I thought I might be able to get the coordinates from Javascript via stringByEvaluatingJavaScriptFromString and I couldn't get that to work either. How can I accomplish this?
A Swift equivalent of this answer: How to detect touch on UIWebView.
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {
let myWebView = UIWebView()
override func viewDidLoad() {
super.viewDidLoad()
myWebView.frame = self.view.frame
self.view.addSubview(myWebView)
myWebView.loadRequest(NSURLRequest(URL: NSURL(string: "https://stackoverflow.com")!))
let webViewTapped = UITapGestureRecognizer(target: self, action: "tapAction:")
webViewTapped.numberOfTouchesRequired = 1
webViewTapped.delegate = self
myWebView.addGestureRecognizer(webViewTapped)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func tapAction(sender: UIGestureRecognizer) {
let point = sender.locationInView(self.view)
println(point.x)
println(point.y)
}
UIView hitTest might be of use.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event ;
Overriding it (or using a category) in your web view might allow you to process tap coordinates of the web view's contained items which wouldn't be passed to the superview by a gesture recognizer

UITextView focused, but user touches UICollectionViewCell. Hide keyboard and run didSelectItemAtIndexPath

I have a "search" UITextField at the top of my view.
Below this, I have a UICollectionView which is populated with the search results as the user types.
When a user is typing into the UITextView, the keyboard is displayed. At first, I wanted to hide the keyboard if the user touched anywhere outside the UITextField. I accomplished this with the following:
func textFieldDidBeginEditing(textField: UITextField) {
if (textField == self.textFieldSearch) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "textFieldSearchDidChange:", name: UITextFieldTextDidChangeNotification, object: textField)
}
var tapGesture = UITapGestureRecognizer(target: self, action: "dismissKeyboard:")
self.view.addGestureRecognizer(tapGesture)
}
func dismissKeyboard(gesture: UIGestureRecognizer) {
self.textFieldSearch.resignFirstResponder()
self.view.removeGestureRecognizer(gesture)
}
However, if the user taps on a UICollectionViewCell, the dismissKeyboard func runs, and hides the keyboard, but the user has to tap on the cell again to run the func:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
How do I do this all in one step? So if the user touches anywhere outside the UITextField, hide the keyboard...but if the user happens to touch a UICollectionViewCell, run the didSelectItemAtIndexPath function on the first touch as well as hide the keyboard and end editing on the UITextField?
Any help is appreciated!
Thanks
Please try this one
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if touch.view == self.textFieldSearch{
return false;
}
else{
return true;
}
}
and add this line in your code
var tapGesture = UITapGestureRecognizer(target: self, action: "dismissKeyboard:")
tapGesture.delegate = self // add gesture delegate here
self.view.addGestureRecognizer(tapGesture)
You can implement the delegate method of UIGestureRecognizerDelegate
optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldReceiveTouch touch: UITouch) -> Bool
Above method returns NO for the views on which gesture recognizer should not be called and in your case it should be collection view else for other things return YES.
example implementation-
/**
Disallow recognition of tap gestures on the collection view.
*/
func gestureRecognizer(recognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool
{
if touch.view == collectionView && recognizer == tapRecognizer {
return false
}
return true
}
Here's a solution. A little janky but it should do the trick. You might have to tinker with it a little. Also my Swift isn't top notch so excuse any syntax errors.
func dismissKeyboard(gesture: UIGestureRecognizer) {
let point : CGPoint = gesture.locationInView(self.collectionView)
let indexPath : NSIndexPath = self.collectionView.indexPathForItemAtPoint(point)
self.textFieldSearch.resignFirstResponder()
self.view.removeGestureRecognizer(gesture)
self.collectionView.selectItemAtIndexPath(indexPath, animated:YES, scrollPosition:UICollectionViewScrollPosition.Top)
}
I am providing here a Objective-C code to dismiss keyBoard on any touch performed outside. Kindly write it in Swift for yourself. The problem is you are adding A tap Gesture which is hiding the touch events of your collection cell.
So instead of tap gesture use the Swift-translated code of the following code.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
Dont use your tap gesture. And I think things should get going for you...
EDIT
Some efforts to write the above code in swift for you...
override func touchesBegan(touches: NSSet, withEvent event: UIEvent){
self.view.endEditing(true)
}
This is the code that ended up finally working, with the help of #Sanjay above.
I still wanted to hide the keyboard if the user touched on the part of the collectionView that wasn't occupied by cells. I will still have to implement code for hiding the keyboard if a user 'swipes/scrolls/drags' on the UICollectionView instead of taps.
For now:
func gestureRecognizer(recognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
for cell:AnyObject in self.collectionView.visibleCells() {
if (touch.view.isDescendantOfView(cell as UIView)) {
self.resignAllResponders()
return false
}
}
return true
}

How to dismiss keyboard when user tap other area outside textfield?

today I tried to run my code on my iPod (iOS 6.1.3) and I found something interesting here...
first, when I tap on textfield the keyboard shows up but it won't hide when I tap somewhere else outside textfield.
so I decided to Googling and found this solution :
_fieldEmail.delegate = self;
_fieldEmail.returnKeyType = UIReturnKeyDone;
_fieldPassword.delegate = self;
_fieldPassword.returnKeyType = UIReturnKeyDone;
_fieldRegisterName.delegate = self;
_fieldRegisterName.returnKeyType = UIReturnKeyDone;
_fieldRegisterEmail.delegate = self;
_fieldRegisterEmail.returnKeyType = UIReturnKeyDone;
_fieldRegisterPassword.delegate = self;
_fieldRegisterPassword.returnKeyType = UIReturnKeyDone;
it works... it gives a 'DONE' button on the bottom of keyboard and now the keyboard can be hidden by pressing it.
but I have 2 problems here :
the keyboard only hide when 'DONE' button is tapped. not by tapping other area outside text field. I don't know if this normal on iOS world, but usually I see lot of apps don't act like this.
is there any way to loop this process so I don't have manually add that delegate one by one of all textfield that I have? how to do that?
that's all I need to know
The below code will work on all the components in the UIView for all the UITextField
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView * txt in self.view.subviews){
if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
[txt resignFirstResponder];
}
}
}
OR
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
Simply add an UITapGestureRecogniser to your view that will lead to calling resignFirstResponder
In viewDidLoad :
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(hideKeyBoard)];
[self.view addGestureRecognizer:tapGesture];
And then :
-(void)hideKeyBoard {
[yourTextField resignFirstResponder];
}
2.You could subclass UITextField but unless you have 1000 textFields it is ok to do like you currently do.
This is regards to Swift programming for Xcode 6.0.1
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleSingleTap:")
tapRecognizer.numberOfTapsRequired = 1
self.view.addGestureRecognizer(tapRecognizer)
}
func handleSingleTap(recognizer: UITapGestureRecognizer) {
self.view.endEditing(true)
}
Use Either
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];
and code of method
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
[self.TextFiledName resignFirstResponder];
}
OR _ And The best Other option is
Just add
[self.view endEditing:YES];
And key board will hide when you tapped anywhere from view:)
Dismissing the keyboard
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
[super touchesBegan:touches withEvent:event];
}
Simple,
Use IQKeyboardManager and put this line of code in AppDelegate.m
[[IQKeyboardManager sharedManager] setShouldResignOnTouchOutside:YES];
What I usually do is call
[field resignFirstResponder];
from an invisible button over the view. I'm sure theres a nicer way to do it. It's been a while since I've done this in an app.
Here's how I do it:
In the myView's .h file:
#property (strong) UITextField * savedTextField;
In the myView's .m file:
#implementation myView
#synthesize savedTextField;
In the myView's init routine:
[self setSavedTextField: nil];
In the myView's textField delegate area I save the id of whichever textField is currently activating:
- (BOOL) textFieldShouldBeginEditing: (UITextField *) textField
{
[self setSavedTextField: textField];
.
.
.
return( YES );
}
And in the myView's routine that routes all the traffic for the other controls when they are accessed, I have code that looks to see if a textField was active and, if one was, it calls on it to resign its FirstResponder status and then drops a nil into the savedTextField property:
- (void) handleCtrlEvents: (UIControl *) aCtrl
{
if ( [self savedTextField] != nil )
{
[[self savedTextField] resignFirstResponder];
[self setSavedTextField: nil];
}
.
.
.
}
This works cleanly for me.
I ran into the exact same problem. Usually what you want is, that wherever you click inside your App (which is displayed in your main / current UIView) but not on the keyboard to close it. After searching the web for a smart solution and testing several, I think it is the best to extend/subclass/implement the UIGestureRecognizerDelegate
Since many controls such as UITableView etc. can respond to gestures (select, scrolling etc.) and if you simply add a UITapGestureRecognizer to the whole (main-)ViewController's view to close the keyboard, the user experience is not the best, since the user needs to tap twice if he didn't intend to close the keyboard but e.g. select a row from a UITableView inside the App's current "main" View.
Since I am quite new to the whole iOS and swift thing and swift code examples are rare, here's my full keyboard control snipped:
class ViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad(){
self.initializeCloseKeyboardTap()
}
func initializeCloseKeyboardTap() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardOpen:", name: UIKeyboardDidShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardClose:", name: UIKeyboardDidHideNotification, object: nil)
let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleOnTapAnywhereButKeyboard:")
tapRecognizer.delegate = self //delegate event notifications to this class
self.view.addGestureRecognizer(tapRecognizer)
}
func onKeyboardClose(notification: NSNotification) {
println("keyboardClosed")
}
func onKeyboardOpen(notification: NSNotification) {
println("keyboardOpen")
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
self.view.endEditing(true)
return false
}
you can nest it inside the ViewController and call initiallizeCloseKeyboardTa() in viewDidLoad implementation... It also implements a norfication observer to receive events as soon as the keyboard (finished to be) opened or closed via NSNotificationCenter UIKeyboardDidShowNotification and UIKeyboardDidHideNotification
Hope that save's other people some time :-)
|*| Dismissing the UITextField’s Keyboard : override the method touchesBegan:withEvent: for the ViewController
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
view.endEditing(true)
super.touchesBegan(touches, withEvent: event)
}
|OR|
override func viewDidLoad()
{
super.viewDidLoad()
// For tapping outside text box
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
}
// For tapping outside text box
func DismisKeyPadFnc()
{
view.endEditing(true)
}
|*| Dismissing the UITextField’s Keyboard on induvidual textbox :
class NamVcc: UIViewController, UITextFieldDelegate
{
#IBOutlet var NamTxtBoxVid: UITextField!
override func viewDidLoad()
{
super.viewDidLoad()
// For hitting return key
NamTxtBoxVid.delegate = self
// For tapping outside text box
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
}
/* For hitting return key */
func textFieldShouldReturn(NamTxtBoxPsgVid: UITextField) -> Bool
{
NamTxtBoxPsgVid.resignFirstResponder()
return true
}
/* For tapping outside text box */
func DismisKeyPadFnc()
{
view.endEditing(true)
}
}
|*| Implementing Next button Click :
1) You will be needing to set the tags in the incremental sequence of the textfields in xib/Storyboard or in code.
2) Set the delegate for each of the textfields.
3) Then paste the following code in your view controller to have the desired effect:
func textFieldShouldReturn(TxtBoxPsgVar: UITextField) -> Bool
{
let NxtTxtBoxTagVal : Int = TxtBoxPsgVar.tag + 1
let NxtTxtBoxVal: UIResponder? = TxtBoxPsgVar.superview?.superview?.viewWithTag(NxtTxtBoxTagVal)
if let TxtBoxVal = NxtTxtBoxVal
{
// Found next responder, so set it.
TxtBoxVal.becomeFirstResponder()
}
else
{
// Not found, so remove keyboard.
TxtBoxPsgVar.resignFirstResponder()
}
return true
}
I prefer IQKeyboardManager. You can simply handle keyboard in any state. To active IQKeyboard just add one line in AppDelegate and to dismiss keyboard on outside touch add code as below,
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
IQKeyboardManager.shared.enable = true
IQKeyboardManager.shared.shouldResignOnTouchOutside = true
return true
}
I think
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
is convenient but not the best solution.
and the TapGestureRecongnizer is better but hard to use,you have to set delegates and add and remove the Recongnizer.
So I wrote a simple subclass which can be easily used:
class TapHideTextField: UITextField {
override func awakeFromNib() {
super.awakeFromNib()
tapGr = UITapGestureRecognizer(target: self, action:"tap")
NSNotificationCenter.defaultCenter().addObserver(self, selector: "didBeginEditing", name:UITextFieldTextDidBeginEditingNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "didEndEditing", name:UITextFieldTextDidEndEditingNotification, object: nil)
}
deinit{
NSNotificationCenter.defaultCenter().removeObserver(self)
}
var tapGr:UITapGestureRecognizer!
func tap(){
self.endEditing(true)
}
func didBeginEditing(){
self.superview!.addGestureRecognizer(tapGr)
}
func didEndEditing(){
self.superview!.removeGestureRecognizer(tapGr)
}
}
you should concern about the superview and the cancelTouchesInView property.
or in GitHub:https://github.com/lilidan/TapHideText/blob/master/TapHideTextField.swift
If you're using scroll view (or table view) controller, add these lines there:
override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
view.endEditing(true)
}
-(void) textFieldDidBeginEditing: (UITextField *) textField{
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(DismissKeyboard:)]];
}
-(void) DismissKeyboard:(UITapGestureRecognizer *) sender{
[self.view endEditing:YES];
[self.view removeGestureRecognizer:sender];
}

How do I implement the UITapGestureRecognizer into my application

I am quite new to programming and Objective C. I was wondering how to make an app which has a blank screen and a timer that goes for one minute. You are meant to tap as fast as you can and as long as you can for. I was wondering how to implement the UITapGestureRecognizer into my code.
This is a step by step guide on how to implement gesture recognizers in your class:
Conform your class to UIGestureRecognizerDelegate protocol.
Instantiate the gesture recognizer. For example, to instantiate a UITapGestureRecognizer, we will do:
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapFrom:)];
Here, action is the selector which will handle the gesture. Here, our selector handleTapFrom will look something like:
- (void) handleTapFrom: (UITapGestureRecognizer *)recognizer
{
//Code to handle the gesture
}
The argument to the selector is the gesture recognizer. We can use this gesture recognizer to access its properties, for example, we can find the state of the gesture recognizer, like, UIGestureRecognizerStateBegan, UIGestureRecognizerStateEnded, etc.
Set the desired properties on the instantiated gesture recognizer. For example, for a UITapGestureRecognizer, we can set the properties numberOfTapsRequired, and numberOfTouchesRequired.
Add the gesture recognizer to the view you want to detect gestures for. In our sample code (I will be sharing that code for your reference), we will add gesture recognizers to an imageView with the following line of code:
[self.imageView addGestureRecognizer:tapGestureRecognizer];
After adding the gesture recognizer to the view, set the delegate for the gesture recognizer, i.e. the class which will handle all the gesture recognizer stuff. In our sample code, it would be like:
tapGestureRecognizer.delegate = self;
Note: Assign the delegate after adding the gesture recognizer to the view. Otherwise, the action method won’t be called.
Example in Swift:
import UIKit
class ViewController: UIViewController {
#IBOutlet var myUIImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let singleTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "myUIImageViewTapped:")
singleTap.numberOfTapsRequired = 1
singleTap.numberOfTouchesRequired = 1
self.myUIImageView.addGestureRecognizer(singleTap)
self.myUIImageView.userInteractionEnabled = true
}
func myUIImageViewTapped(recognizer: UITapGestureRecognizer) {
if(recognizer.state == UIGestureRecognizerState.Ended){
println("myUIImageView has been tapped by the user.")
}
}
}
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];
self.tableView.userInteractionEnabled = YES;
gestureRecognizer.cancelsTouchesInView = NO; // this prevents the gesture recognizers to 'block' touches
Works in Xcode 11.4, Swift 5
class ViewController: UIViewController {
#IBOutlet weak var targetView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(self.touchCallback(_:)))
self.targetView.addGestureRecognizer(tap)
}
#objc func touchCallback(_ sender: UITapGestureRecognizer? = nil) {
if(sender?.state == .ended) {
print("tapped")
}
}
}
// If you want to touch start, available touchesBegan
class ViewController: UIViewController {
#IBOutlet weak var targetView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: targetView)
print(location)
}
}
}
If you are working Swift (iOS9) and SpriteKit, try the following.
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
let singleTap = UITapGestureRecognizer(target:self, action:#selector(self.handleSingleTap:))
singleTap.numberOfTouchesRequired = 1
singleTap.addTarget(self, action:#selector(self.handleSingleTap))
view.userInteractionEnabled = true
view.addGestureRecognizer(singleTap)
}
//event handler
func handleSingleTap(sender:UITapGestureRecognizer){
print("tapped")
}
}

Resources