Horizontal scroll on UIScrollView without pan gesture - ios

How can I make it so that when I use my UIScrollView the pan gesture recognizer selector is not called.
I want to be able to scroll in the scroll view without the pan gesture selector being called.
Here is my pan detected function:
- (void)panDetected:(UIPanGestureRecognizer *)panRecognizer
{
CGPoint translation = [panRecognizer translationInView:self.view];
CGPoint imageViewPosition = self.draggableImage.center;
imageViewPosition.x += translation.x;
imageViewPosition.y += translation.y;
self.draggableImage.center = imageViewPosition;
[panRecognizer setTranslation:CGPointZero inView:self.view];
}
I do not want it to be called when I am using my UIScrollView at the bottom of the page.

you could remove the gesture recognizer from the scroll view
NSArray* gestureRecognizers = [scrollView gestureRecognizers];
for (UIGestureReconizer* recog in gestureRecognizers) {
if ( [recog isKindOfClass:[UIPanGestureRecognizer Class]] )
[recog removeTarget:scrollView.delegate action:#selector(scrollViewDidScroll:)];
}
I don't understand why this is needed to be done, but here it is.

Not exactly sure what you're trying to accomplish here. I haven't played with this, but my initial thought is that if you disable the pan recognizer, your scroll view isn't gonna scroll. Your scrollview calculates where and how to scroll based on the what the pan recognizer is telling it.
If you have an alternative setup to handle the scrolling, then by all means:
UIScrollView *scrollView;
[[scrollView panGestureRecognizer] setEnabled:NO];

Related

UIPinchGestureRecognizer Disable Pinch Out

I have added a pinch gesture recognizer to a scroll view, using it to close a modal view controller. I did it like so:
UIPinchGestureRecognizer *closePinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(closeGallery)];
[galleryScrollView addGestureRecognizer:closePinch];
Although it is added to a scrollView, I do not actually use it to zoom only to close the view. Therefore, I have no need for the pinch-out gesture as it indicates zooming in.
Is there a way to easily disable the pinch-out portion of the gesture recognizer and leave the pinch-in untouched?
Based on Crazyrems' answer, the following delegate method did exactly what I needed:
- (BOOL)gestureRecognizerShouldBegin:(UIPinchGestureRecognizer *)gestureRecognizer
{
// Negative velocity indicates pinch out
if (gestureRecognizer.velocity < 0) {
return YES; // <- Register touch event
} else {
return NO; // <- Do not register touch event
}
}
You should implement -gestureRecognizerShouldBegin: in your UIGestureRecognizerDelegate
There's a velocity property in the recognizer passed in parameter, so you can check if it's a pinch in or out, and return YES or NO in consequence.

UIPanGestureRecognizer conflicts with UIPinchGestureRecognizer's superview

I have a UIScrollView instance with a subview that has its own UIPanGestureRecognizer which is used to move the subview inside the scrollview. I would like the pinch-to-zoom feature of the scrollview to have the top priority over the pan gesture. However, this is not the case: when starting to pinch with one finger over my subview, it will pan instead.
What I tried so far:
gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:: it will pan AND pinch
[panGestureRecognizer requireGestureRecognizerToFail:scrollView.pinchGestureRecognizer];: panning just won't work anymore (callback is triggered only for UIGestureRecognizerStateEnded state). And panGestureRecognizer.cancelsTouchesInView = NO won't help.
My understanding is that when starting to pinch from the subview, both the scroll view and the subview only receive one touch each, that's why in the second case the pinch gesture recognizer doesn't even fail because it doesn't even begin to handle the event.
So, any idea on how to achieve this?
One way to do it is to allow simultaneous interaction with the scrollView.pinchGestureRecognizer, and then cancel the panGestureRecognizer if the scrollView.pinchGestureRecognizer is actually zooming. The only way I know how to cancel them is to disable/enable.
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
if (gestureRecognizer == panGestureRecognizer){
if (otherGestureRecognizer == scrollView.panGestureRecognizer) {
return 0;
}
else if(otherGestureRecognizer == scrollView.pinchGestureRecognizer){
if (scrollView.pinchGestureRecognizer.scale != 1) {
gestureRecognizer.enabled = 0;
gestureRecognizer.enabled = 1;
}
}
}
return 1;
}

How to get pan gesture to move a label horizontally and disappear?

I want to get the same effect as here:
I have set a UIPanGestureRecognizer and I can move the label around, this is how I did it:
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
This is the method in the view controller, of course I added a pan gesture object to the xib file and set the proper connections.
And I also know the method that get it to disappear:
[self.homeLabel removeFromSuperview];
But how can I make the same effect as in the gif?
I also have an image property for the v sign called vSignImage.
I want to be able to move it only horizontally to the right, make the v sign slide in from the left after I moved the label x px to the right, and when I release my finger I want the label to disappear.
Please help :)
Thanks!!
Don't use any kind of gesture recognizer. Just put the label in a little horizontal-only scroll view. Now the user can only slide the label horizontally. Now use the delegate to detect / govern what happens as the user slides the label. This is how swipe-to-delete works in Apple's Mail program, for example.

iOS: Tap Recognizer not consistent

I have a scenario like shown below
Right now, I am showing only 1 view with label 8. But I am planning to add 3 more such views to the HolderView.
The SmallerView/s are created from other Nib files.
I did this code for adding Tap Recognizer for ViewController's view
UITapGestureRecognizer *tapRecognizer=[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapRecognized2:)];
[tapRecognizer setDelegate:self];
[self.view addGestureRecognizer:tapRecognizer];
Code for adding Tap Recognizer to the smaller views
I added smaller views to the HolderView. And assigned Tag IDs to them. After that,
for (SmallerView *view in HolderView.subviews) {
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecognized:)];
[recognizer setDelegate:self];
NSLog(#"Added gesture to the view with tag: %ld",view.tag);
[view addGestureRecognizer:recognizer];
}
3.
- (void)tapRecognized:(UITapGestureRecognizer *)paramSender
{
NSLog(#"tapped on %ld", paramSender.view.tag);
}
- (void)tapRecognized2:(UITapGestureRecognizer *)paramSender
{
NSLog(#"VC view");
}
I have enabled UserInteraction (both in code and Inspector) for all the views and UILabels on smaller views too.
The problem now is...
The smaller view's Tap recognisers are not really working consistently. Sometimes they print the output. All at suddenly it prints the ViewController's recogniser's output.
Please help
UPDATE:
Below is my View diagram.
Green Border: (In UIView's initWithFrame)d
self.layer.borderColor = [UIColor greenColor].CGColor;
Red Border:
MyTile *tile = [[[NSBundle mainBundle] loadNibNamed:#"View" owner:self options:nil] objectAtIndex:0];
self.myLabel.layer.borderColor=[UIColor redColor].CGColor;
Why that Green Border is coming only of that size? Shouldn't that be full square?
And, the gesture works only when I tap on the green area. Why?
It seems that you have a tap gesture recognizer on a view and also a tap gesture recognizer on its superview. The way gesture recognizers work is that, by default, both of them will be candidates to recognize the tap. If that is not what you want, it is up to you to prevent it.
You can:
set up a "you-go-first" relationship between the gesture recognizers, or
you can use their delegates to help decide between them, or
you can set up the subview so that it stops the superview's gesture recognizer from recognizing.
You have lots of options!
But if you do none of them, then both this view's gesture recognizer and its superview's gesture recognizer will be trying to recognize.
Perhaps a better solution would just to add one tapGestureRecognizer to the parent view.
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]init];
tap.numberOfTapsRequired = 1;
tap.numberOfTouchesRequired = 1;
[tap addTarget:self action:#selector(handleTap:)];
[holderView addGestureRecognizer:tap];
Then add the target method
- (void) handleTap:(UITapGestureRecognizer *)tap {
UIView * holderView;
CGPoint tapPoint = [tap locationInView:holderView];
for (UIView * v in holderView.subviews) {
if (CGRectContainsPoint(v.frame, tapPoint)) {
// v is the subview that was pressed.
// add your code here.
break;
}
}
}
I have assigned a new frame to the frame which was having wrong borders. This helped in getting the gestures right.

Strikethrough Text with Animation iOS

What is the best way to display a strikethrough animation? When a user swipes their finger across a UITableViewCell, I would like to animate a thin line across cell.textlabel.text
The two ways I've thought of so far would be using Animation or somehow displaying a custom image and revealing it slowly from left to right? Does anybody have any advice on this?
I already have the swipe gestures working, I now just need to know how to make the animation happen:
Add Gesture Recognizer:
//Add a left swipe gesture recognizer
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSwipeLeft:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[self.tableView addGestureRecognizer:recognizer];
//Add a right swipe gesture recognizer
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSwipeRight:)];
recognizer.delegate = self;
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.tableView addGestureRecognizer:recognizer];
Delegate Methods for Gestures:
- (void)handleSwipeLeft:(UISwipeGestureRecognizer *)gestureRecognizer
{
NSLog(#"uncompleted");
}
// Cross Item off of the list
- (void)handleSwipeRight:(UISwipeGestureRecognizer *)gestureRecognizer
{
NSLog(#"completed");
}
Based on what you have so far the following should work:
when handleSwipeLeft (or right) fires, place a new UIView with a black background color over the textfield at the textfield's x point and around halfway to the y point with a width of 0 and height of 1
then, call [UIView animationWithDuration....] changing the UIView's width property to be roughly the width of the textfield.
This should be close to what you want with some tweaking. I don't think it will be possible to animate the strikethrough from using the properties of the font alone but this technique should simulate it just fine.
Good job on getting half way there.

Resources