UILabel move to point without snapping - ios

I have a UILabel which I have added a GestureRecognizer to. I am able to drag it around the screen fine but what I am wanting to do is when the label is within an area I want it to stop dragging and have it move smoothly to a designated point within that area.
So if it's x value is greater than 150 move it to x of 200 and y of 150
It does work but it's popping to the location instead of being smoothly moved to the location.
Here is my drag method:
- (void)labelDragged:(UIPanGestureRecognizer *)gesture {
UILabel *label = (UILabel *)gesture.view;
CGPoint translation = [gesture translationInView:label];
// move label
label.center = CGPointMake(label.center.x + translation.x,
label.center.y + translation.y);
[gesture setTranslation:CGPointZero inView:label];
if (label.center.x > 150){
[label setUserInteractionEnabled:NO];
[UIView animateWithDuration:1.5 animations:^{
label.center = CGPointMake(200 , 150);
}];
}
}
Any help would be appreciated. I'm new to working with animation and points.

you have to wait till panGesture state.So condition required.While using pan gesture you removed userInteraction from label.By removing User Interaction it doesn't remove gesture from UILabel that's why this is happening.To work animation on UILabel you have to leave UILabel after dragging.Remove finger from label and it will animate.Use following code.
- (void)labelDragged:(UIPanGestureRecognizer *)gesture {
UILabel *label = (UILabel *)gesture.view;
CGPoint translation = [gesture translationInView:label];
// move label
label.center = CGPointMake(label.center.x + translation.x,
label.center.y + translation.y);
[gesture setTranslation:CGPointZero inView:label];
if (label.center.x > 150){
[label setUserInteractionEnabled:NO];
if(gesture.state == UIGestureRecognizerStateEnded)
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"position"];
[animation setFromValue:[NSValue valueWithCGPoint:label.center]];
[animation setToValue:[NSValue valueWithCGPoint:CGPointMake(200.0f, 400.0f)]];
[animation setDuration:2.0f];
[label.layer setPosition:CGPointMake(200.0f, 400.0f)];
[label.layer addAnimation:animation forKey:#"position"];
}
}
}

If you really want to cancel the UIPanGestureRecognizer while it is still being performed, you can do so. Set the enabled property to NO, and enable it back on completion of the animation.
if (label.center.x > 150){
gesture.enabled = NO;
[label setUserInteractionEnabled:NO];
[UIView animateWithDuration:1.5 animations:^{
label.center = CGPointMake(200 , 150);
} completion:^(BOOL finished) {
gesture.enabled = YES;
}];
}
But then once the label is snapped, you will not be able to drag it since the gesture will always be disabled due to the position of the label. It is better to snap the label when the gesture is ended.
if (gesture.state == UIGestureRecognizerStateEnded) {
//check the position and snap the label
}

Related

Slide up UIView following finger similar to Control Center in iOS

I have a UITableView that is at the bottom of my main UIViewController, it currently only shows the top two rows. To show the rest I don't want it to scroll, I want the user to be able to "pull" the view up to reveal the additional 4 rows (can then swipe down on it to "push" it back into its original place), and I want the "pull" to be similar to how control center works in iOS. The spring that it has is really great.
Looks like I can add a UIPanGestureRecognizer to do the pull:
UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(pan:)];
pan.maximumNumberOfTouches = pan.minimumNumberOfTouches = 1;
[self addGestureRecognizer:pan];
- (void)pan:(UIPanGestureRecognizer *)aPan; {
CGPoint currentPoint = [aPan locationInView:self];
[UIView animateWithDuration:0.01f
animations:^{
CGRect oldFrame = _viewToChange.frame;
_viewToChange.frame = CGRectMake(oldFrame.origin.x, currentPoint.y, oldFrame.size.width, ([UIScreen mainScreen].bounds.size.height - currentPoint.y));
}];
}
Ref this question.
Doing this does sort of work, but my UITableView flashes as you pull it up and it eventually disappears.
There is also no spring, and no way to set a "max" so that you can't pull up the view past a certain point.
Does anyone have ideas on how this can be achieved?
this is how i write the pan:. t is tableView(initially user interaction is disabled). 40 in code is for more realistic look in pan. 200 is max value i used and 60 is min value. i directly add t to tableview with height 60 and increased the height with animation.
- (void)pan:(UIPanGestureRecognizer *)aPan; {
CGPoint currentPoint = [aPan locationInView:self.view];
CGRect fr = t.frame;
if ((currentPoint.y - fr.origin.y) < 40 && (fr.size.height <= 200) )
{
float nh = (currentPoint.y >= self.view.frame.size.height - 200) ? self.view.frame.size.height-currentPoint.y : 200;
if (nh < 60) {
nh = 60;
}
[UIView animateWithDuration:0.01f animations:^{
[t setFrame:CGRectMake(0, self.view.frame.size.height-nh, t.frame.size.width, nh)];
}];
if (nh == 200) {
[t setUserInteractionEnabled:YES];
}
else
{
[t setUserInteractionEnabled:NO];
}
}
}
or without pan; with using tableview's scrollview delegate methods, when tableview begin dragging in closed state, opening the large mode and when tableview scroll to top sliding down
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
NSLog(#"scroll");
if (scrollView.contentOffset.y == 0) {
[UIView animateWithDuration:0.2f animations:^{
[scrollView setFrame:CGRectMake(0, self.view.frame.size.height-200, t.frame.size.width, 200)];
}];
}
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y == 0) {
[UIView animateWithDuration:0.2f animations:^{
[scrollView setFrame:CGRectMake(0, self.view.frame.size.height-60, t.frame.size.width, 60)];
}];
}
}

Pang Gesture Recognizer stop

want to use a UIView like a UIScrollView for more reason, i create a Action with PanGestureRecognizer that's the simple code:
- (IBAction)moveUp:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.containerView];
recognizer.view.center = CGPointMake(recognizer.view.center.x, recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
But i want to stop dragging when my containerView bottom is in exact position, follow the screens:
This is the full viewController, all button you see is inside a containerView
This is when i open the application:
The header image is in a ViewController below and all button you see is inside a containerView, now i want to fix this position with absolute y, my containerView can't drag down.
Now the function can't stop, when i dragUp this is what happen:
My containerView can drag over the end of the containerView and i don't want that is possible, i want block the drag up in the end of containerView like this screen:
And when i drag down again i want to stop drag in starter position (screen 1).
Thanks for any idea.
What you are trying to achieve sounded fun to me at first glance, so I wanted to give it a try.
I modified your gesture recognizer's call back to the following:
- (IBAction)panned:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:yourContainerView];
CGFloat yWithinBounds = 0.0f;
if(recognizer.view.center.y + (recognizer.view.bounds.size.height / 2.0f) > yourContainerView.bounds.size.height)
{
yWithinBounds = yourContainerView.bounds.size.height - (recognizer.view.bounds.size.height / 2.0f);
[UIView animateWithDuration:1.0f animations:^
{
recognizer.view.center = CGPointMake(recognizer.view.center.x, yWithinBounds);
}];
}
else if(recognizer.view.center.y - (recognizer.view.bounds.size.height / 2.0f) < yourContainerView.bounds.origin.y)
{
yWithinBounds = yourContainerView.bounds.origin.y + (recognizer.view.bounds.size.height / 2.0f);
[UIView animateWithDuration:1.0f animations:^
{
recognizer.view.center = CGPointMake(recognizer.view.center.x, yWithinBounds);
}];
}
else
{
recognizer.view.center = CGPointMake(recognizer.view.center.x, recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0.0f, 0.0f) inView:self.view];
}
}
In the first if, we are checking if the current center point of your contained view + half the size of it is going out of bounds of the containing view on the bottom; if it is, instead of simply disallowing it to go further, I took the liberty of putting this in an animation block to animate the contained view back to within the containing view so that it looks a bit better visually.
In the else-if, we are doing the same except this time for the top of the containing view - we are checking if the contained view is going out of bounds on top; if it is, we animate it back within the containing view.
If the else clause is reached, that would mean the contained view is within the containing view's bounds - here, we simply translate it like you originally do.
Here is how I set up the views as test:
yourContainerView = [[UIView alloc] initWithFrame:self.view.bounds];
yourContainerView.backgroundColor = [UIColor brownColor];
[self.view addSubview:yourContainerView];
UIView *viewWithinContainer = [[UIView alloc] initWithFrame:(CGRect){{yourContainerView.bounds.origin.x, yourContainerView.bounds.origin.y}, yourContainerView.bounds.size.width, 50.0f}];
viewWithinContainer.backgroundColor = [UIColor yellowColor];
[yourContainerView addSubview:viewWithinContainer];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panned:)];
[viewWithinContainer addGestureRecognizer:panGesture];
Feel free to adjust the height (i.e., 50.0f to other values) of the view (hereby: the viewWithinContainer) within the container; the way the code is set up, you would not need to change any other values else where even if you change the height.
You could also change the animation duration to your need.
I am moving the thing up and down in my simulator at the moment; looks simple but fun to play around.
Update after question update:
Your new update seems to differ somewhat greatly from what you originally asked, but here is the solution:
The complexity is direction. There are other ways to find out; but I am using mine here, through which we don't need to create another variable.
If you are using storyboard, please set up an IBOutlet for your container view, because we would like to obtain the following values (carry out the following in initWithFrame and initWithCoder):
p1 = viewWithinContainer.center.y;
p2 = viewWithinContainer.center.y - (yourContainerView.bounds.size.height - viewWithinContainer.bounds.size.height);
Please set up p1 and p2 as ivars:
CGFloat p1;
CGFloat p2;
Here is the updated method for a contained view larger than the containing view:
- (IBAction)panned:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:yourContainerView];
if(translation.y < 0)
{
if(recognizer.view.center.y + (recognizer.view.bounds.size.height / 2.0f) + translation.y > yourContainerView.bounds.size.height) {
recognizer.view.center = CGPointMake(recognizer.view.center.x, recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
else
{
recognizer.view.center = CGPointMake(recognizer.view.center.x, p2);
[recognizer setTranslation:translation inView:self.view];
}
}
else if(translation.y > 0)
{
if(recognizer.view.center.y - (recognizer.view.bounds.size.height / 2.0f) + translation.y < yourContainerView.bounds.origin.y)
{
recognizer.view.center = CGPointMake(recognizer.view.center.x, recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
else
{
recognizer.view.center = CGPointMake(recognizer.view.center.x, p1);
[recognizer setTranslation:translation inView:self.view];
}
}
}
The method will ensure that, as you scroll down, the top of the contained view will stop at the edge of the container on top; and as you scroll up, at the edge of the container on the bottom.
I ran this in the simulator; and japp, it has been fun doing this. Enjoy. :-)

iOS adding an animation with Pan Gesture Recognizer

I'm trying to make an animation within a pan gesture recognizer. However, when the recognizer gets to my desired location on the screen, the UIStateGestureRecognizerStateEnded gets called, and my animation does not get fired properly. This is how I am going about doing that. How can I make it so that my animation is smooth and doesn't disrupt the gesture recognizer's state.
-(IBAction)handlePan:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x, recognizer.view.center.y + translation.y);
self.lineView1.center = CGPointMake(self.lineView1.center.x, recognizer.view.center.y + translation.y - 337.5f);
self.lineView2.center = CGPointMake(self.lineView2.center.x, recognizer.view.center.y +translation.y + 337.5f);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
//THIS CODE IS NOT ALLOWING THE ANIMATION TO RUN SMOOTHLY? AND ENDS THE GESTURE'S STATE.
if ((recognizer.view.center.y + translation.y)>300 && (recognizer.view.center.y + translation.y)<345) {
[UIView animateWithDuration:3.5 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
self.joinHorzConst.constant= 60;
self.joinLabel.alpha = 1;
} completion:^(BOOL finished) {
//completion
}];
}
if (recognizer.state == UIGestureRecognizerStateEnded) {
[UIView animateWithDuration:.35 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
recognizer.view.center = CGPointMake(recognizer.view.center.x, 121.5f);
self.lineView1.center = CGPointMake(281, -216);
self.lineView2.center = CGPointMake(281, 459);
} completion:^(BOOL finished) {
[UIView animateWithDuration:.2 animations:^{
recognizer.view.center = CGPointMake(recognizer.view.center.x, 147.5f);
self.lineView1.center = CGPointMake(281, -189);
self.lineView2.center = CGPointMake(281, 486); } completion:^(BOOL finished) {
[UIView animateWithDuration:.1 animations:^{
recognizer.view.center = CGPointMake(recognizer.view.center.x, 141.5f);
self.lineView1.center = CGPointMake(281, -196);
self.lineView2.center = CGPointMake(281, 479);
}];
}];
}];
}
}
Thanks in advance!
EDIT: Exactly how I want my animation to work:
user drags a recognizer up and down a y axis, like a slider. When the slider button reaches within certain y axises (300 - 345), I want there to be an animation on one of my labels that just pushes it to the left a bit and turns the alpha up.
How it is working right now:
Right now, the slider works fine, UNTILL i reach the y axis between 300-345, at that point my gestureReconizerStatedidEnd gets called and the slider returns to its original position with the desired animation. I dont want this to happen. I want the slider to keep moving freely, but the label animation to happen just as the slider is within those 300-345 dimensions.
The way I was setting the labels x value with constraints seemed to be disrupting the gesture? Not sure. But here is how it is working now.
if ((recognizer.view.center.y + translation.y)>300 && (recognizer.view.center.y + translation.y)<345) {
[UIView animateWithDuration:.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
[self.joinLabel setCenter:CGPointMake(183, 324)];
self.joinLabel.alpha = 1;
} completion:^(BOOL finished) {
//completion
}];
}

Little hiccup in the animation after UIPanGestureRecognizer state is end

I'm trying to achieve dragging of view and when the drag stops, the view slide to top and disappear. I can use UIPanGestureRecognizer to drag the view fine. But after that, I used animation to let it slide out. The problem is that after the drag, there's always a little hiccup before the view moves... I searched around and can't figure out how to solve this. Here is the code:
- (void)moveView2:(UIPanGestureRecognizer *)pan {
CGPoint delta = [pan translationInView:self.view];
CGPoint newCenter = CGPointMake(_view2.center.x, _view2.center.y + delta.y);
_view2.center = newCenter;
[pan setTranslation:CGPointZero inView:self.view];
if (pan.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [pan velocityInView:self.view];
NSLog(#"Velocity is %f, %f", velocity.x, velocity.y);
// Here is the delay
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.5f initialSpringVelocity:500 options:UIViewAnimationOptionCurveEaseInOut animations:^{
_view2.center = CGPointMake(_view2.center.x, -600);
} completion:nil];
}
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIButton *fbButton;
#property (weak, nonatomic) IBOutlet UIButton *twitterButton;
#property UIView *view1;
#property UIView *view2;
#property CGPoint startPoint;
#property CGPoint endPoint;
#property CGPoint originCenter;
#property double startTime;
#property double endTime;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CGRect frame = [UIScreen mainScreen].bounds;
_view1 = [[UIView alloc] initWithFrame:frame];
_view1.backgroundColor = [UIColor redColor];
[self.view addSubview:_view1];
_view2 = [[UIView alloc] initWithFrame:frame];
_view2.backgroundColor = [UIColor greenColor];
[self.view addSubview:_view2];
UIPanGestureRecognizer *pan1 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveView2:)];
[_view2 addGestureRecognizer:pan1];
/*
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeUpDown:)];
[swipe setDirection:UISwipeGestureRecognizerDirectionUp];
[_view2 addGestureRecognizer:swipe];
*/
}
/*
- (void)swipeUpDown:(UISwipeGestureRecognizer *)swipe {
if (swipe.direction == UISwipeGestureRecognizerDirectionUp) {
NSLog(#"Swipe up");
[UIView animateWithDuration:0.5 animations:^{
_view2.center = CGPointMake(_view2.center.x, -600);
}];
}
}*/
- (void)moveView2:(UIPanGestureRecognizer *)pan {
CGPoint bigViewDelta = [pan translationInView:self.view];
CGPoint newCenter = CGPointMake(_view2.center.x, _view2.center.y + bigViewDelta.y);
_view2.center = newCenter;
[pan setTranslation:CGPointZero inView:self.view];
if (pan.state == UIGestureRecognizerStateEnded) {
CGPoint velocityOfPan = [pan velocityInView:self.view];
CGFloat velocityOfPanAbsolute = sqrt(velocityOfPan.x * velocityOfPan.x + velocityOfPan.y * velocityOfPan.y);
// get simple points per second
CGPoint currentPoint = _view2.center;
CGPoint finalPoint = CGPointMake(_view2.center.x, -600);
CGFloat distance = sqrt((finalPoint.x - currentPoint.x) * (finalPoint.x - currentPoint.x) + (finalPoint.y - currentPoint.y) * (finalPoint.y - currentPoint.y));
// how far to travel
CGFloat duration = 0.5;
CGFloat animationVelocity = velocityOfPanAbsolute / (distance / duration);
[UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:1.0 initialSpringVelocity:animationVelocity options:0 animations:^{
_view2.center = CGPointMake(_view2.center.x, -600);
} completion:nil]; }
}
- (void)viewDidAppear:(BOOL)animated {
/*
[UIView transitionFromView:_view2 toView:_view1 duration:2 options:UIViewAnimationOptionCurveEaseInOut completion:^(BOOL finished) {
}];
*/
/*
// get the view that's currently showing
UIView *currentView = _view2;
// get the the underlying UIWindow, or the view containing the current view view
UIView *theWindow = [currentView superview];
// remove the current view and replace with myView1
[currentView removeFromSuperview];
//[theWindow addSubview:newView];
// set up an animation for the transition between the views
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[theWindow layer] addAnimation:animation forKey:#"SwitchToView1"];
*/
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Do you mean a delay before the animation takes place? Hmm, I'm not seeing anything that would cause that, but the parameters to animateWithDuration are very, very curious.
First, UIViewAnimationOptionCurveEaseInOut doesn't makes sense to me, because that's used to say "start slowly, pick up speed, and stop slowly, too". That's fine with a standard animation where you don't want the starting of the animation to be too jarring. But it doesn't make sense in this context because you presumably want it not to start slowly, but rather to use whatever velocity you initially provided. If I used any option, I'd use UIViewAnimationOptionCurveEaseOut. Even that doesn't make sense, because it's the usingSpringWithDamping parameter that dictates what happens at the end of this animation. (And, on top of all of that, you're dragging it off screen, so I'm unclear why you care about the exit curve anyway.)
Second, the initialSpringVelocity is doesn't seem at all right to me, either. As the documentation for this parameter says:
The initial spring velocity. For smooth start to the animation, match this value to the view’s velocity as it was prior to attachment.
A value of 1 corresponds to the total animation distance traversed in one second. For example, if the total animation distance is 200 points and you want the start of the animation to match a view velocity of 100 pt/s, use a value of 0.5.
So, 500 means that you want to travel 500 times the distance between the current location and the final location in one second. That's absurdly fast.
I would try to match the initial velocity with the final velocity of gesture. So, calculate the absolute velocity of the gesture, and divide that by the distance to be traveled divided by the duration of the animation.
Third, if you're dragging it off screen, I'm not sure why you're using a usingSpringWithDamping of 0.5. That's springy. And why would you want it to spring at all you're using as it stops off screen and you can't see it anyway? It strikes me that any value less than 1.0 risks the possibility of the view springing back into the visible screen during one or more of the initial springs. I wouldn't use anything less than 1.0 here if animating off screen.
Pulling that all together, I get something like:
CGPoint velocityOfPan = [pan velocityInView:self.view];
CGFloat velocityOfPanAbsolute = hypof(velocityOfPan.x, velocityOfPan.y); // get simple points per second
CGPoint currentPoint = _view2.center.x;
CGPoint finalPoint = CGPointMake(_view2.center.x, -600);
CGFloat distance = hypof(finalPoint.x - currentPoint.x, finalPoint.y - currentPoint.y); // how far to travel
CGFloat duration = 0.5;
CGFloat animationVelocity = velocityOfPanAbsolute / (distance / duration);
[UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:1.0 initialSpringVelocity:animationVelocity options:0 animations:^{
_view2.center = CGPointMake(_view2.center.x, -600);
} completion:nil];
Having said all of that, while it's possible animateWithDuration is getting confused by the combination of "ease in-ease out" and the dramatic initialSpringVelocity, I don't actually see why that would cause a "hiccup".
Are you doing anything else immediately after this animation? Anything that might be blocking the main queue?
Do you mean the little delay before the gesture is first recognized? Yes, that's a feature of pan gesture recognizer. (I think it's trying to determine whether it's really a pan vs long press vs, etc.).
You can get around this by using a UILongPressGestureRecognizee with minimumPressDuration of zero (though you have to calculate translationInView yourself).

Which label did the user last touch and how to remove it from the view

I want to know how to know which label the user last touched and how to remove that specific label from the view. I know how to change the properties for all labels, but I don't know how to find out which one was last selected.
This is how I add a label to the view.
myNewLabel.text =textField.text;
numberOfLabels++;
myNewLabel.tag=numberOfLabels;
[self.view addSubview:myNewLabel];
[shirtBackgroundView addSubview:myNewLabel];
[myNewLabel addGestureRecognizer:panGestureRecognizer];
[myNewLabel addGestureRecognizer:rotateGestureRecognizer];
[myNewLabel addGestureRecognizer:PinchGestureRecognizer];
myNewLabel.userInteractionEnabled=YES;
myNewLabel.backgroundColor=[UIColor clearColor];
[arrayForLabels addObject:myNewLabel];
Here is how I change the color of all labels.
for(int i=0;i<numberOfLabels;i++)
{
UILabel *tempLabel = [arrayForLabels objectAtIndex:i];
tempLabel.textColor=[UIColor redColor];
}
-(void)labelMoved:(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];
}
}
Thanks for any suggestions...
For detect UIlabels to capture taps:
label.userInteractionEnabled = YES;
UIGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecieved:)];
[label addGestureRecognizer:tap];
[tap release];
//repeat for each additional label
when you touched
-(void) tapRecieved:(UITapGestureRecognizer *)tap{
currentLabel = (UILabel *) tap.view;
[currentLabel removeFromSuperview];
}
You can declare a property in .h class as UILabel *lastSelectedLabel; and in your recognizer
-(void)labelMoved:(UIPanGestureRecognizer *)recognizer{
if(lastSelectedLabel!=nil){
[lastSelectedLabel removeFromSuperview];
lastSelectedLabel=recognizer.view;
}else
lastSelectedLabel=recognizer.view;
}
I think above should work..
Thanks.

Resources