UIButton and swipe-to-delete on UITableViewCell - ios

I have a custom UITableViewCell with a UIButton.
UIButton blocks the swipe-to-delete gesture recognizer implemented by Apple; if the swipe starts on the button, the swipe is not recognized, otherwise the delete button appears and everything works correctly
At the moment, I have replace the UIButton by an UIImageView to get the desired behaviour.
I would like if somebody manages to make this work.
I have already tried to implement this delegate method
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
and searched the view/subviews for all its gesture recognizers and assign them the cell as delegate. I still can make it work with a UIButton.
I target ios8
Thanks

Use UILable or UIImage instead of UIButton, and set userInteractionEnabled to YES, and add a UITapGestureRecognizer gesture to it.

Related

How to avoid to trigger a UIPanGestureRecognizer when there is a tap on a UIButton?

I have added UIPanGestureRecognizer on the view of my UIViewController.
In this view (a calculator) are some UIButton triggered by the event .TouchUpInside.
The problem comes if I tap on the button and make a small pan at the same time (which might happen if you tap quickly a button and are moving to the next one at the same time). Then the pan gesture is triggered. I would like to avoid it when there is a tap on a button. But I would like to allow it if the tap takes too long (let say 0.3s is enough to trigger the pan gesture).
How can I achieve that?
Set the property cancelsTouchesInView of your gesture recognizer to NO.
Then your button should work properly.
You can use the delegate method like this-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isKindOfClass:[UIButton class]]) {
return NO;
}
return YES;
}
There is a dirty solution. You can just grab it in a UIScrollView

Tap Gesture Recognizer for View but not Sub-View in CustomView

I have created a customViewController to act as a customActionsheet. In this customViewController I have a UIView as the main view (self.view) and an IBOutlet UIView that is the custom action sheet (actionSheetView). What I am trying to do is make this custom action sheet act like a regular actionsheet where if you tap in the dark area, in my case the view with blackColor background and alpha 5.0. This is what I have:
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(slideOut)];
tapGesture.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:tapGesture];
The problem with this is that the subview, the custom action sheet view, also gets the tapgesture so tapping anything on the actionSheetView will get the tap gesture. I have tried a few things like - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch and self.actionSheetView.userInteractionEnabled = NO; but both do not seem to work. Anyone have any idea of how I can make the self.view tappable but disable that gesture for self.actionSheetView? Any tips, guidance, or help is greatly appreciated. Thanks in advance.
I was working on this same style of system. I found it works if you:
Add a new UIView as a subview of the main UIView.
Create another UIView where you want the custom UI (could be a table like an action sheet, a picker, etc). Make sure this shows above the UIView in step 1.
Register the UITapGestureRecognizer on the UIView from step 1.
(Optional) Add extra buttons (e.g. "Cancel" and "Done") and set up a delegate that your custom controller fires.
The main UIView (self.view) should be opague, clear color with alpha of 1. The full subview (see step 1) can be any color (I used light gray color), but adjust the alpha value (0.5 for me).
Unfortunately I can't post an image because I don't have enough rep on the site yet.
If you're using IB and having trouble receiving taps, check under the Attributes Inspector (under the view section) to make sure that "User Interaction" is enabled.
You need to set the delegate
tapGesture.delegate = self.actionSheetView
//actionSheetView.m
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
return NO;
}

Passing UIGestureRecognizer events to child TableViewCells

I currently have a setup of:
A RootVC, with a UIPanGestureRecognizer on self.view. Then the RootVC has a child UITableViewController and hence UITableViewController.view is a subview of self.view.
The cells on the UITableViewController also have gesture recognizers enabling them to be swiped sideways. This works perfectly when the UITableViewController is itself the root view controller.
My issue is that im trying to pass a specific gesture from the self.view gesture recognizer down to the table cells. I've tried delegates:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
and
-(BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
I can correctly identify the gestures i want to be sent below and return NO in that instance but that seems to cancel the gesture instead of passing it to subviews.
I know i could just call
[self.view.subviews[0] gestureShouldBegin:gestureRecognizer];
But because its the table view cells i cannot determine which cell the gesture should be sent too.
I have been thinking something like
[[self.childViewControllers[0] cellForRowAtIndexPath:indexPath] gestureShouldBegin:gestureRecognizer];
Would work but i dont know how to determine the correct indexPath..
Any ideas?
Look at (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point
You'll need to translate the point of the gesture to the coordinates for the tableView first.

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.

Two UIGestureRecognizers and UIButton

I encountered this problem and was able to resolve it as described.
Gesture recognizer and button actions
But when I added a second UIGestureRecognizer to the same UIView the UIButton selector is not called for the second UIGestureRecognizer, only the first.
So I have a single UIView with two UIGestureRecognizers. There is a UIButton on the UIView.
The UIButton selector always get called correctly after the first UIGestureRecognizer. The first touch on the UIButton for the second UIGestureRecognizer does nothing, but the second touch on the UIButton works as expected.
If I remove the first UIGestureRecognizer from the view then the first UIButton press fires the selector as expected after the second gesture is performed.
Any idea why the first touch on the UIButton doesn't fire the selector but the second does?
try to put his delegate method in your viewController
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
returning YES to this method is guaranteed to allow simultaneous recognition.

Resources