Pass tap event to the subview iOS - ios

I have a TTTAttributed Label which detect link on it by self and I have a tap gesture on it which perform some action.
The problem is when I have a tap gesture on it then it cant be able to open the link It only can perform the action by tap gesture But I want that if the text is link type then my tap gesture do forward the tap to the link detection of TTTAttributed label.
Your effort is truly appreciate. Thanks in advance.

label.enabledTextCheckingTypes = NSTextCheckingTypeLink; // Automatically detect links when the label text is subsequently changed
label.delegate = self; // Delegate methods are called when the user taps on a link (see `TTTAttributedLabelDelegate` protocol)
label.text = #"Google it! (https://www.google.co.in/)"; // Repository URL will be automatically detected and linked
NSRange range = [label.text rangeOfString:#"Google"];
[label addLinkToURL:[NSURL URLWithString:#"http://google.com/"] withRange:range]; // Embedding a custom link in a substring
Set the delegate of the TTTAttributed label and when the user will tap on the label its delegate method will get invoked.
(void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url
Handle your event in this delegate method.

Check for the [UITapGestureRecognizer state] property in your tap gesture recogniser delegate method. Based on the state value, pass on the event to following touch delegate methods of your TTTAttributedLabel object, after you are done with your custom tap gesture handling:
- touchesBegan:withEvent:
- touchesMoved:withEvent:
- touchesEnded:withEvent:
- touchesCancelled:withEvent:
This should take care of executing the default behaviour of the TTTAttributedLabel class.

Related

Get UITapGestureRecognizer to recognize touches when they begin?

Is there any way to get UITapGestureRecognizer to run on touch began?
I can't use touchesBegan because I am using a UITableView and the super view steals the event essentially.
I just want to detect when the screen is first touched. Why is this so difficult? Maybe I need a different solution than using tapgesturerecognizer?
You can use state property of UIGestureRecognizer to identify various states of any gesture -
#property(nonatomic,readonly) UIGestureRecognizerState state; // the current state of the gesture recognizer
So when the gesture begin, use something like this in your registered handler method -
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
// Do your stuff
}
You can add a tap gesture recognizer to the tableView in viewDidLoad like this:
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureRecognized:)];
[self.tableView addGestureRecognizer:tapGestureRecognizer];
Then implement this method:
- (void)tapGestureRecognized:(UITapGestureRecognizer *)tapGestureRecognizer {
NSLog(#"tap gesture recognized");
}
Just tested this out, and works fine. For every tap i get the log message on my console. Note that this prevents the tableview from receiving the taps, other gestures will just be handled by the table view as usual.
You need to set delaysContentTouches = NO

Cancel gesture recognizer on button action

I'm working on an iPad app. I have a view in which the user can draw with his finger. This view has a subview, which is a calculator, and which have buttons.
I would like that when the user touch a button, the superview (in which the user can draw) doesn't take into account this touch. (so the user doesn't draw when he touches the calculator)
Preferably, I would like to not change the code of the calculator view and the code of my superview. I have only access to them via properties of another class.
Is there a way to solve the problem please? I have tried exclusiveTouch, but it doesn't work.
If you have access to the button action and the drawing gesture you can simply set:
gesture.enabled = NO;
To cancel the current gesture processing and / or prevent it from starting. When you want to reenable the gesture depends on what type it is and how it's used but doing it immediately (on the next line) will probably work ok.
Try this but include UIGestureRecognizerDelegate in your header file.
This is from apple "SimpleGestureRecognizers" example-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// Disallow recognition of tap gestures in the segmented control.
if ((touch.view == YourButton))
{
//change it to your condition
return NO;
}
return YES;
}

Homemade tap gesture recognizer for iOS

I'd like to code my own tap gesture recognizer, to detect the number of taps and number of touches (I don't want to use the iOS tap gesture recognizer because I want to extend it later in various other manners) ;
I tried the following : use the first motionBegin number of touches as the numberOfTouches of the tap, increment the numberOfTaps, and start the tap detection timer to detect the tap gesture if no new taps has been seen in a while
The problem is that one quickly realises that when doing a double-touch tap gesture, iOS either correctly detects one motionBegin with a double touch, or two quick one touch events. I guess a correct implementation should try to detect those quick one touch events that happen closely, but I'm wondering if there is a better way to implement the gesture recognizer.
Someone knows how the iOS tap gesture is implemented?
1. Add UIGestureRecognizerDelegate in your .h file. like
#interface finalScreenViewController : UIViewController <UIGestureRecognizerDelegate>
{
// do your stuff
}
2. Create a view in your viewDidLoad method (or any other method) you wanna to add the gesture in your .m file
ex
UIView * myView=[[UIView alloc]init];
myView.frame=CGRectMake(0,0.self.view.frame.size.width,self.view.frame.size.height);
[self.view addSubView: myView];
UITapGestureRecognizer *letterTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapMethod:)];
letterTapRecognizer.numberOfTapsRequired = 1;
[myView addGestureRecognizer:letterTapRecognizer];
3. you can get view by
- (void) tapMethod:(UITapGestureRecognizer*)sender {
UIView *view = sender.view;
NSLog(#"%d", view.tag);//By tag, you can find out where you had tapped.
}

CustomTextField - AutoComplete/AutoCorrect won't dismiss on tap

So I created a custom text view using core graphics and have it conformed to the UITextInput and UITextInputTraits protocols. Everything works fine except for one weird/annoying behavior. The keyboard correctly displays auto correct suggestions, but when the use taps on a suggestion labelled with an 'X', it doesn't dismiss the suggestion but instead inserts the suggestion. I've checked, and in all other programs tapping on the a suggestion with an 'X' dismisses the suggestion. How do I fix this?
In my custom text view I have the following iVars:
//UITextInputTraits
UITextAutocapitalizationType _uiAutoCap;
UITextAutocorrectionType _uiAutoCorrect;
UITextSpellCheckingType _uiSpellCheck;
UIKeyboardType _uiKeyboard;
UIKeyboardAppearance _uiKeyboardAppearance;
UIReturnKeyType _uiReturnType;
BOOL _uiEnableAutoReturn;
BOOL _uiSecureText;
Which are synthesized to the appropriate TextInputTraits properties:
#synthesize autocapitalizationType=_uiAutoCap, autocorrectionType=_uiAutoCorrect, spellCheckingType=_uiSpellCheck, keyboardType=_uiKeyboard, keyboardAppearance=_uiKeyboardAppearance, returnKeyType=_uiReturnType, inputDelegate=_uiTextDelegate, enablesReturnKeyAutomatically=_uiEnableAutoReturn, secureTextEntry=_uiSecureText;
And they're initialized with the following default values:
_uiAutoCorrect = UITextAutocorrectionTypeDefault;
_uiSpellCheck = UITextSpellCheckingTypeDefault;
_uiKeyboardAppearance = UIKeyboardAppearanceDefault;
_uiAutoCap = UITextAutocapitalizationTypeNone;
_uiReturnType = UIReturnKeyDefault;
_uiEnableAutoReturn = NO;
_uiSecureText = NO;
_uiKeyboard = UIKeyboardTypeDefault;
Any ideas?
Edit: Possible answer
When you tap to close the suggestion, your tap is likely intercepted by your view first which presumably changes the selected range of the text (which causes UITextInput to accept the suggestion). Not the best solution, but UITextInput calls
- (NSDictionary *)textStylingAtPosition:(UITextPosition *)position inDirection:(UITextStorageDirection)direction;
when it wants to make a suggestion, so, you could have an ivar (BOOL) that stores whether or not there is a suggestion (make its value NO whenever a UIKeyInput method is called and YES when the textStyling method is called). Then, modify your gesture recognizer so that it will not change the selection if the aforementioned ivar is YES and the tap is in the rect of the suggestion box (You could get this rect by doubling the height of the rect returned from - (CGRect)firstRectForRange:(UITextRange *)range;). Hope that works.
Edit: you should just be able to implement the UIGestureRecognizerDelegate method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
So that it only receives a touch if touch.view == (yourTextView)
I am having the same issue, and don't yet have a solution; however, I do believe that you should conform to UITextInputTraits by creating functions that return the value you would like for the property. Example: for the trait UITextAutoCorrectionType to have a value of UITextAutocorrectionTypeDefault, you should provide an accessor method:
- (UITextAutocorrectionType)autocorrectionType {
return UITextAutocorrectionTypeDefault;
}

IBAction UIButton firing is delayed

I have a UIButton connected to an IBAction in Interface Builder.
The Problem:
The action firing and the de-highlight of the button both take a little bit to happen.
The Facts:
View structure:
View
10 Buttons (connected via UIControlEventTouchUpInside to the IBAction
View (Subview)
Gesture recognizer
Text Field
The Subview has a UITapGestureRecognizer, which delaysTouchesBegan and delaysTouchesEnded both are set to NO
The action is happening in the main thread.
Testing a simple button (with no images or title, and only a simple NSLog), the result is the same
The Question:
Why are firing and the de-highlight delayed?
In the end, I added somewhere some UIGestureRecognizer, and forgot to set delaysTouchesBegan to NO =(
Ok I think that because of the UITapGestureRecognizer .. try to do the following :
connect an IBOutlet to your button.
2.assing the UITapGestureRecognizer delegate to your ViewController.
3.Implement this gesture delegate method in yourViewController
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch {
return (! [yourButton pointInside:[touch locationInView:yourButton] withEvent:nil]);
}
This will make the tap to be recognized to your button not to the recognizer.
Make sure your touch event is set the first contact of the button which would be the touch down event otherwise there will be a delay in the action until whichever other event you chose gets completed (i.e. touch up inside, touch up outside, etc).
In my case, there was a delay on IBAction for a button that was in a custom CalloutView of an MKAnnotationView.
In the same way there is a ~0.5sec delay between pressing the MKAnnotationView and the MKAnnotationView actually being selected, there is also a delay between any other user interactions you might add as a subview of the MKAnnotationView.
The solution is to disable the native UIGestureRecognizer within MapView that is causing the delay of any MKAnnotation view selections.
This can be done with the solution on this post:
Set isZoomEnabled = false within a gesture recognizer attached to the mapview on any tap, then set isZoomEnabled = false within a 0.5sec async dispatch.

Resources