Locking UIPanGestureRecognizer to a certain direction - ios

I have UIPanGestureRecognizer and I'm trying to get it only swipe in one direction (up).
I haven't been able to find a solution that works. Thanks.
This is my current code:
- (void)panGesture:(UIPanGestureRecognizer *)recognizer{
CGPoint t = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + t.x, recognizer.view.center.y + t.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}

- (void)panGesture:(UIPanGestureRecognizer *)recognizer {
CGPoint t = [recognizer translationInView:self.view];
if (t.y < 0) {
t = CGPointMake(0, t.y);
}
else {
t = CGPointMake(0, 0); // look at this
}
recognizer.view.center = CGPointMake(recognizer.view.center.x + t.x,
recognizer.view.center.y + t.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
To be able to drag up and down use CGPointMake(0, t.y); instead of my if

Related

How to simulate a touch on iOS

I would like to know if there isn't any method which will allow me to simulate a touch/click/pressure (call it as you want) on iOS.
I don't know if I have something to add about this... Except that I'm coding with Objective-c.
Every help will be appreciated, thanks in advance!
EDIT:
Here is the method that allow me to have the coordinates of the case that I've selected (it show me in the log) :
- (void)collectionViewTableLayoutManager:(DRCollectionViewTableLayoutManager *)manager collectionView:(UICollectionView *)collectionView didSelectCellAtRow:(NSUInteger)row column:(NSUInteger)column indexPath:(NSIndexPath *)indexPath
{
NSLog(#"SELECTED: %ld.%ld / %ld.%ld", (long)indexPath.section, (long)indexPath.row, (long)row, (long)column);
}
Here is my method who handle the dragNdrop of my PostIt (see in the comments for more info):
-(IBAction)handlePan:(UIPanGestureRecognizer *)recognizer{
CGPoint translation = [recognizer translationInView:self];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);
//Here to know the coordinates of the drop
if(recognizer.state == UIGestureRecognizerStateEnded){
CGPoint centerPointOfView = [recognizer locationInView:self.superview];
NSLog(#"X - %f, Y - %f",centerPointOfView.x,centerPointOfView.y);
}
[recognizer setTranslation:CGPointMake(0, 0) inView:self];
}
So here is how I solved my problem. Initially, the method who handle the postIt's dragNdrop was in the postIt.m . So I moved it into my viewController.m . Now, from this method, I'm able to pick up the CollectionView of my viewController and "simulate" a click.
Here is how my new method looks like:
-(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);
//the coordinates of the drop
if(recognizer.state == UIGestureRecognizerStateEnded){
CGPoint centerPointOfView = [recognizer locationInView:self.view];
NSLog(#"X - %f, Y - %f",centerPointOfView.x,centerPointOfView.y);
//Here is how I pick up the cell where the post it has been dropped
[_collectionView cellForItemAtIndexPath:[_collectionView indexPathForItemAtPoint:centerPointOfView]];
NSIndexPath *indexPath =[_collectionView indexPathForItemAtPoint:centerPointOfView];
//some log tests
NSLog(#"SELECTED: %ld.%ld ", (long)indexPath.section, (long)indexPath.row);
}
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}

Pan Gesture Recognizer reset

I've added a pan gesture to my button, when i move it without any additional code, everything is well, but when i add some piece of code, which is commented in the example below, button starts reseting to its origin position.
Why is this happening? What's the reason for this?
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
switch([recognizer state]){
case UIGestureRecognizerStateBegan: {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:recognizer.view.frame];
[button setBackgroundColor: [UIColor redColor]];
// [self.view insertSubview:button belowSubview:recognizer.view];
_tempButton = button;
}break;
case UIGestureRecognizerStateChanged: {
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];
}break;
}
}
The code that you have added at the UIGestureRecognizerStateChanged case, move it in the header of your Action Method:
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];
After that another thing for you to do is to make another Case in your Switch Method:
//This checks if you ended the pan gesture (removed finger from object)
case UIGestureRecognizerStateEnded:
{
CGPoint velocity = [recognizer velocityInView:self.view];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(#"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor),
recognizer.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
recognizer.view.center = finalPoint;
} completion:nil];
}
So what I did above in the UIGestureRecognizerStateEnded state is that, i took the final point where the user sent the image. After that, i set the center of the image equal to the point that the image was the last moment. So now the image wont return to the previous point but it will remain where the user will take it.

How to get the coordinate of a UIView

In my app, I use PanGesture.
Now, I have a UIImageView within my main view and I can drag my UIImageView within the main view.
To which axis in the main view I have to drag my UIImageView?
Try this to move your object
or link for best tutorials http://www.raywenderlich.com/6567/uigesturerecognizer-tutorial-in-ios-5-pinches-pans-and-more
- (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];
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [recognizer velocityInView:self.view];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(#"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor),
recognizer.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
recognizer.view.center = finalPoint;
} completion:nil];
}
}
you can use frame property of a UIView class.which gives you top,left,width and height of the view.
NSLog(#"view.frame.origin.x : %f",view.frame.origin.x);
NSLog(#"view.frame.origin.y : %f",view.frame.origin.y);
NSLog(#"view.frame.size.width : %f",view.frame.size.width);
NSLog(#"view.frame.size.height : %f",view.frame.size.height)
You can use below APIs to translate your points from one view to other and vice versa.
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view;
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view;
- (IBAction)panGestureReceived:(UIPanGestureRecognizer *)gesture {
if ([gesture state] == UIGestureRecognizerStateBegan) {
myVarToStoreTheBeganPosition = [gesture locationInView:self.view];
} else if ([gesture state] == UIGestureRecognizerStateEnded) {
CGPoint myNewPositionAtTheEnd = [gesture locationInView:self.view];
// and now handle it ;)
} else if ([gesture state] == UIGestureRecognizerStateChanged) {
CGPoint myNewPositionAtTheEnd = [gesture locationInView:self.view];
// and now handle it ;)
}
}

UIGestureRecognizer, making panned picture return to its original location

I'm new to Objective-C. I'm making a simple app where I need a picture to move down to the bottom to the screen when pulled with finger. And then the picture should go back to its original location. How do I achieve this? This is what I have so far but I can't figure out the returning of the picture.
#implementation TestiAppViewController
-(IBAction)controlPan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.view];
if ((recognizer.view.center.y + translation.y < 320) && (recognizer.view.center.y + translation.y > 100)) {
recognizer.view.center = CGPointMake(recognizer.view.center.x,recognizer.view.center.y + translation.y);
}
[recognizer setTranslation:CGPointMake(0,0) inView:self.view];
NSLog(#"Ended Center: %#", NSStringFromCGPoint(recognizer.view.center));
}
I think add return statement. hope it would work
if ((recognizer.view.center.y + translation.y < 320) && (recognizer.view.center.y + translation.y > 100)) {
recognizer.view.center = CGPointMake(recognizer.view.center.x,recognizer.view.center.y + translation.y);
return;
}

Disabling Pan Gesture if out of bounds detected

I have a UIView I am trying to move up and down the screen, however I only wish to enable it to pan so that you cannot drag the view down when it is in its normal position (0, 0)
I tried to detect when the recognizer's center is not half the height of the view, however the view is then immovable, and the center is always half the height (230 in this case).
Any ideas?
- (IBAction)panDetected:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.view];
NSLog(#"\ncenter.y: %f\ntranslation.y: %f\n", recognizer.view.center.y, translation.y);
if (recognizer.view.center.y > ([[UIScreen mainScreen] bounds].size.height - 20)/2) {
return;
}
recognizer.view.center = CGPointMake(recognizer.view.center.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
Instead of manually computing whether the points are within the view's bounds, use CGRectContainsPoint(rect, point). This is what works for me, and I like it because it's shorter and more readable:
func handlePan(pan: UIPanGestureRecognizer) {
switch pan.state {
case .Began:
if CGRectContainsPoint(self.pannableView.frame, pan.locationInView(self.pannableView)) {
// Gesture started inside the pannable view. Do your thing.
}
}
CGPoint translation = [recognizer translationInView:self.view];
CGPoint finalpoint = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y+ translation.y);
//limit the boundary
if ((recognizer.view.frame.origin.x>0 && translation.x > 0) || (recognizer.view.frame.origin.x + recognizer.view.frame.size.width<=320 && translation.x < 0))
finalpoint.x = recognizer.view.center.x;
if ((recognizer.view.frame.origin.y>0 && translation.y > 0) || (recognizer.view.frame.origin.y + recognizer.view.frame.size.height<=self.view.frame.size.height && translation.y < 0))
finalpoint.y = recognizer.view.center.y;
//set final position
recognizer.view.center = finalpoint;
[recognizer setTranslation:CGPointZero inView:self.view];
try
CGPoint translation = [recognizer translationInView:self.view];
if (translation.x+recognizer.view.frame.origin.x<0||translation.y+recognizer.view.frame.origin.y<0)
{
return;
}
recognizer.view.center = CGPointMake(recognizer.view.center.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x, MAX(recognizer.view.center.y + translation.y, ([[UIScreen mainScreen] bounds].size.height - 20)/2));

Resources