Scale Font size with UITextview resizing - ios

i want to create UITextView which is scaled and rotate with one finger touch(Pan gesture).But problem is the text Font size is not scaled properly. Please help.
it works,but not perfectly.
-(void)resizeTranslate:(UIPanGestureRecognizer *)recognizer
{
if ([recognizer state]== UIGestureRecognizerStateBegan)
{
prevPoint = [recognizer locationInView:vw_txtfield.superview];
[vw_txtfield setNeedsDisplay];
olddistance = sqrt(pow((vw_txtfield.frame.origin.x - prevPoint.x), 2.0) + pow((vw_txtfield.frame.origin.y - prevPoint.y), 2.0));
}
else if ([recognizer state] == UIGestureRecognizerStateChanged)
{
CGPoint point = [recognizer locationInView:vw_txtfield.superview];
newdistance = sqrt(pow((vw_txtfield.frame.origin.x - point.x), 2.0) + pow((vw_txtfield.frame.origin.y - point.y), 2.0));
float wChange = 0.0, hChange = 0.0;
wChange = newdistance / olddistance ;//Slow down increment
NSLog(#"wchange %f",wChange);
hChange= newdistance / olddistance;
NSLog(#"hchange %f",hChange);
if (txt_LableText.font.pointSize<=6 && wChange<1) {
return;
}
else
{
vw_txtfield.bounds = CGRectMake(vw_txtfield.bounds.origin.x, vw_txtfield.bounds.origin.y, vw_txtfield.bounds.size.width * (wChange), vw_txtfield.bounds.size.height * (hChange));
[txt_LableText setContentScaleFactor: newdistance / olddistance ];
float int_NewFontsize= ( newdistance / olddistance) * txt_LableText.font.pointSize;
NSLog(#"font size %f",int_NewFontsize);
[txt_LableText setFont:[UIFont fontWithName:txt_LableText.font.fontName size:int_NewFontsize]];
prevPoint = [recognizer locationInView:vw_txtfield.superview];
[vw_txtfield setNeedsDisplay];
olddistance = sqrt(pow((vw_txtfield.frame.origin.x - point.x), 2.0) + pow((vw_txtfield.frame.origin.y - point.y), 2.0));
}
}
else if ([recognizer state] == UIGestureRecognizerStateEnded)
{
prevPoint = [recognizer locationInView:vw_txtfield.superview];
[vw_txtfield setNeedsDisplay];
}
}

Related

how to stop moving image when image is not zoomed in?

I have a UIImageView i am performing pinch zoom & move image on full zoom.I am able to move the image but the issue is even if the image is not zoomed in it still moves on the screen.Please tell me how can i prevent it?
Here is the code for that
#define MINIMUM_SCALE 0.5
#define MAXIMUM_SCALE 6.0
#property CGPoint translation;
- (void)pan:(UIPanGestureRecognizer *)gesture {
static CGPoint currentTranslation;
static CGFloat currentScale = 0;
if (gesture.state == UIGestureRecognizerStateBegan) {
currentTranslation = _translation;
currentScale = self.view.frame.size.width / self.view.bounds.size.width;
}
if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [gesture translationInView:self.view];
_translation.x = translation.x + currentTranslation.x;
_translation.y = translation.y + currentTranslation.y;
CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x , _translation.y);
CGAffineTransform transform2 = CGAffineTransformMakeScale(currentScale, currentScale);
CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
self.view.transform = transform;
}
}
- (void)pinch:(UIPinchGestureRecognizer *)gesture {
if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {
// NSLog(#"gesture.scale = %f", gesture.scale);
CGFloat currentScale = self.view.frame.size.width / self.view.bounds.size.width;
CGFloat newScale = currentScale * gesture.scale;
if (newScale < MINIMUM_SCALE) {
newScale = MINIMUM_SCALE;
}
if (newScale > MAXIMUM_SCALE) {
newScale = MAXIMUM_SCALE;
}
CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x, _translation.y);
CGAffineTransform transform2 = CGAffineTransformMakeScale(newScale, newScale);
CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
self.view.transform = transform;
gesture.scale = 1;
}
}
**PS:**ImageView should only move when image is zoomed otherwise it should not be moveable.
I suggest a different approach:
Create a UIScrollView add the UIImageView into the scrollView's contentView and allow scrolling and zooming on the scrollView.
To prevent scrolling when not zoomed, set setScrollEnabled to NO and enable it in scrollViewDidZoom if the zoomLevel reaches a custom threshold.
So sth. like this should make make it much easier what you're trying to accomplish with a lot less code.
- (void)viewDidLoad:(BOOL)animated {
[super viewDidLoad:animated];
self.scrollView.scrollEnabled = NO;
self.scrollView.minimumZoomScale = 1;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
if (scrollView.zoomLevel > 1) {
scrollView.scrollEnabled = YES;
} else {
scrollView.scrollEnabled = NO;
}
}
I re-post the code I gave you in your first question on the subject ( Pinch zoom shifting image to most left corner on iPad in iOS? ), because I think the way you do it does not work as expected ( as far as I have tested ).
The pinch zoom is supposed to zoom on the middle of the fingers, and not on the middle of the image. If you really want to apply the zoom on center, I have added a boolean property zoomOnCenter.
The boundaries checking is done in the translateBy method.
Here is a link on the xCode test project: https://drive.google.com/file/d/0B88aMtNA0z2aWVBIbGZGdVhpdWM/view?usp=sharing
Interface
#interface PinchViewController : UIViewController
#property(nonatomic,strong) IBOutlet UIView* contentView;
#property(nonatomic,assign) BOOL zoomOnCenter;
#end
Implementation
#implementation PinchViewController
{
CGPoint translation;
CGFloat scale;
CGAffineTransform scaleTransform;
CGAffineTransform translateTransform;
CGPoint previousTranslation;
CGFloat previousScale;
NSUInteger previousNumTouches;
}
-(void)viewDidLoad
{
scale = 1.0f;
scaleTransform = CGAffineTransformIdentity;
translateTransform = CGAffineTransformIdentity;
previousTranslation = CGPointZero;
previousNumTouches = 0;
UIPinchGestureRecognizer *pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(handlePinch:)];
[self.view addGestureRecognizer:pinch];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[panGesture setMinimumNumberOfTouches:1];
[panGesture setMaximumNumberOfTouches:1];
[self.view addGestureRecognizer:panGesture];
}
-(void)handlePinch:(UIPinchGestureRecognizer*)recognizer
{
// 1 - find pinch center
CGPoint mid = self.zoomOnCenter ? CGPointZero : [self computePinchCenter:recognizer];
mid.x-= recognizer.view.bounds.size.width / 2.0f;
mid.y-= recognizer.view.bounds.size.height / 2.0f;
// 2 - compute deltas
NSUInteger numTouches = recognizer.numberOfTouches;
if ( (recognizer.state==UIGestureRecognizerStateBegan) || ( previousNumTouches != numTouches ) ) {
previousScale = recognizer.scale;
previousTranslation = mid;
previousNumTouches = numTouches;
}
CGFloat deltaScale = ( recognizer.scale - previousScale ) * scale;
previousScale = recognizer.scale;
CGPoint deltaTranslation = CGPointMake(mid.x-previousTranslation.x, mid.y-previousTranslation.y);
previousTranslation = mid;
deltaTranslation.x/=scale;
deltaTranslation.y/=scale;
// 3 - apply
scale+=deltaScale;
if (scale<0.01) scale = 0.01; else if (scale>10) scale = 10;
scaleTransform = CGAffineTransformMakeScale(scale, scale);
[self translateBy:deltaTranslation];
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
if (recognizer.state==UIGestureRecognizerStateBegan) previousTranslation = CGPointZero;
CGPoint recognizerTranslation = [recognizer translationInView:self.contentView];
CGPoint deltaTranslation = CGPointMake(recognizerTranslation.x - previousTranslation.x,recognizerTranslation.y - previousTranslation.y);
previousTranslation = recognizerTranslation;
[self translateBy:deltaTranslation];
}
-(void)translateBy:(CGPoint)delta
{
CGSize contentSize = self.contentView.bounds.size;
CGSize viewSize = self.view.bounds.size;
CGSize scaledViewSize = viewSize;
scaledViewSize.width/=scale;
scaledViewSize.height/=scale;
CGPoint maxTranslation = CGPointMake( (contentSize.width-scaledViewSize.width) / 2.0f , (contentSize.height-scaledViewSize.height) / 2.0f );
if ( contentSize.width*scale < viewSize.width ) {
delta.x=0;
translation.x = 0;
} else {
translation.x+=delta.x;
if ( translation.x < - maxTranslation.x ) {
translation.x = - maxTranslation.x;
}
else if ( translation.x > maxTranslation.x ) {
translation.x = maxTranslation.x;
}
}
if ( contentSize.height*scale < viewSize.height ) {
delta.y=0; translation.y = 0;
} else {
translation.y+=delta.y;
if ( translation.y < - maxTranslation.y ) {
translation.y = - maxTranslation.y;
}
else if ( translation.y > maxTranslation.y ) {
translation.y = maxTranslation.y;
}
}
translateTransform = CGAffineTransformMakeTranslation(translation.x,translation.y);
self.contentView.transform = CGAffineTransformConcat(translateTransform,scaleTransform);
}
-(CGPoint)computePinchCenter:(UIPinchGestureRecognizer*)recognizer
{
// 1 - handle up to 3 touches
NSUInteger numTouches = recognizer.numberOfTouches;
if (numTouches>3) numTouches = 3;
// 2 - Find fingers middle point - with (0,0) being the center of the view
CGPoint pt1,pt2,pt3,mid;
switch (numTouches) {
case 3:
pt3 = [recognizer locationOfTouch:2 inView:recognizer.view];
case 2:
pt2 = [recognizer locationOfTouch:1 inView:recognizer.view];
case 1:
pt1 = [recognizer locationOfTouch:0 inView:recognizer.view];
}
switch (numTouches) {
case 3:
mid = CGPointMake( ( ( pt1.x + pt2.x ) / 2.0f + pt3.x ) / 2.0f, ( ( pt1.y + pt2.y ) / 2.0f + pt3.y ) / 2.0f );
break;
case 2:
mid = CGPointMake( ( pt1.x + pt2.x ) / 2.0f, ( pt1.y + pt2.y ) / 2.0f );
break;
case 1:
mid = CGPointMake( pt1.x, pt1.y);
break;
}
return mid;
}
#end
You can check the frame of your imageView and if it is same it means imageview has not been zoomed So you can disable the pan gesture if frame of imageview is same ......and if frame has changed then you can enable the pan gesture.....

Pinch zoom shifting image to most left corner on iPad in iOS?

I have a image in iOS. I have added pinch gesture on the image when i pinch the image it shifted to top left corner. I have also added pan gesture on image. When an image is zoomed then i am scrolling the image in every direction for that purpose i have added the pan gesture into the image.
My code is :
-(void)viewDidLoad
{
UIPinchGestureRecognizer *pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(handlePinch:)];
[self.zoom_image addGestureRecognizer:pinch];
panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveImage:)];
[panGesture setMinimumNumberOfTouches:1];
[panGesture setMaximumNumberOfTouches:1];
[self.zoom_image addGestureRecognizer:panGesture];
img_center_x = self.zoom_image.center.x;
img_center_y = self.zoom_image.center.y;
}
-(void)handlePinch:(UIPinchGestureRecognizer*)sender
{
NSLog(#"latscale = %f",mLastScale);
mCurrentScale += [sender scale] - mLastScale;
mLastScale = [sender scale];
NSLog(#"before ceneter x %f",img_center_x);
NSLog(#"before ceneter x %f",img_center_y);
CGPoint img_center = CGPointMake(img_center_x, img_center_y);
self.zoom_image.center = img_center;
if (sender.state == UIGestureRecognizerStateEnded)
{
mLastScale = 1.0;
}
if(mCurrentScale<1.0)
{
mCurrentScale=1.0;
}
if(mCurrentScale>3.0)
{
mCurrentScale=3.0;
}
CGAffineTransform currentTransform = CGAffineTransformIdentity;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform,mCurrentScale, mCurrentScale);
self.zoom_image.transform = newTransform;
}
Pan gesture
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveImage:)];
[panGesture setMinimumNumberOfTouches:1];
[panGesture setMaximumNumberOfTouches:1];
[self.zoom_image addGestureRecognizer:panGesture];
move image:
- (void)moveImage:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:self.zoom_image];
CGPoint location = [recognizer locationInView:self.view];
CGPoint initial=CGPointZero;
NSLog(#"%f\n%f",translation.x,translation.y);
NSLog(#"%f",self.zoom_image.frame.origin.y);
CGPoint finalpoint = CGPointMake(self.zoom_image.center.x + translation.x, self.zoom_image.center.y+ translation.y);
NSLog(#"%f",finalpoint.y);
//limit the boundary
if(recognizer.state==UIGestureRecognizerStateChanged)
{
if ((self.zoom_image.frame.origin.x>0 && translation.x > 0) || (self.zoom_image.frame.origin.x + self.zoom_image.frame.size.width<=self.view.frame.size.width && translation.x < 0))
finalpoint.x = self.zoom_image.center.x;
if ((self.zoom_image.frame.origin.y>100 && translation.y > 0) || (self.zoom_image.frame.origin.y + self.zoom_image.frame.size.height<=self.view.frame.size.height && translation.y < 0))
finalpoint.y = self.zoom_image.center.y;
//set final position
NSLog(#"%f",finalpoint.y);
self.zoom_image.center = finalpoint;
[recognizer setTranslation:initial inView:self.zoom_image];
}
}
Here is a possible solution.
• I've renamed your zoom_image by contentView, because this class can manipulate any view, not only images.
• I've removed the bound tests, and let the scale be in ( 0.01 - 10.0 )
• The pinch handle up to three fingers, and also acts as pan. Number of touches can be changed without interrupting the pinch.
There is still many things to improve, but the main principle is here :)
Interface ( properties like minScale,maxScale, minMargin and so are still to be added - why not a delegate )
#interface PinchViewController : UIViewController
#property(nonatomic,strong) IBOutlet UIView* contentView;
#end
Implementation
#implementation PinchViewController
{
CGPoint translation;
CGFloat scale;
CGAffineTransform scaleTransform;
CGAffineTransform translateTransform;
CGPoint previousTranslation;
CGFloat previousScale;
NSUInteger previousNumTouches;
}
-(void)viewDidLoad
{
scale = 1.0f;
scaleTransform = CGAffineTransformIdentity;
translateTransform = CGAffineTransformIdentity;
previousTranslation = CGPointZero;
previousNumTouches = 0;
UIPinchGestureRecognizer *pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(handlePinch:)];
[self.view addGestureRecognizer:pinch];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[panGesture setMinimumNumberOfTouches:1];
[panGesture setMaximumNumberOfTouches:1];
[self.view addGestureRecognizer:panGesture];
}
-(void)handlePinch:(UIPinchGestureRecognizer*)recognizer
{
// 1 - find pinch center
CGPoint mid = [self computePinchCenter:recognizer];
mid.x-= recognizer.view.bounds.size.width / 2.0f;
mid.y-= recognizer.view.bounds.size.height / 2.0f;
// 2 - compute deltas
NSUInteger numTouches = recognizer.numberOfTouches;
if ( (recognizer.state==UIGestureRecognizerStateBegan) || ( previousNumTouches != numTouches ) ) {
previousScale = recognizer.scale;
previousTranslation = mid;
previousNumTouches = numTouches;
}
CGFloat deltaScale = ( recognizer.scale - previousScale ) * scale;
previousScale = recognizer.scale;
CGPoint deltaTranslation = CGPointMake(mid.x-previousTranslation.x, mid.y-previousTranslation.y);
previousTranslation = mid;
deltaTranslation.x/=scale;
deltaTranslation.y/=scale;
// 3 - apply
scale+=deltaScale;
if (scale<0.01) scale = 0.01; else if (scale>10) scale = 10;
scaleTransform = CGAffineTransformMakeScale(scale, scale);
[self translateBy:deltaTranslation];
NSLog(#"Translation : %.2f,%.2f - Scale Center : %.2f,%.2f - Scale : %.2f",deltaTranslation.x,deltaTranslation.y,mid.x,mid.y,scale);
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
if (recognizer.state==UIGestureRecognizerStateBegan) previousTranslation = CGPointZero;
CGPoint recognizerTranslation = [recognizer translationInView:self.contentView];
CGPoint deltaTranslation = CGPointMake(recognizerTranslation.x - previousTranslation.x,recognizerTranslation.y - previousTranslation.y);
previousTranslation = recognizerTranslation;
[self translateBy:deltaTranslation];
NSLog(#"Translation : %.2f,%.2f - Scale : %.2f",deltaTranslation.x,deltaTranslation.y,scale);
}
-(void)translateBy:(CGPoint)delta
{
translation.x+=delta.x;
translation.y+=delta.y;
translateTransform = CGAffineTransformMakeTranslation(translation.x,translation.y);
self.contentView.transform = CGAffineTransformConcat(translateTransform,scaleTransform);
}
-(CGPoint)computePinchCenter:(UIPinchGestureRecognizer*)recognizer
{
// 1 - handle up to 3 touches
NSUInteger numTouches = recognizer.numberOfTouches;
if (numTouches>3) numTouches = 3;
// 2 - Find fingers middle point - with (0,0) being the center of the view
CGPoint pt1,pt2,pt3,mid;
switch (numTouches) {
case 3:
pt3 = [recognizer locationOfTouch:2 inView:recognizer.view];
case 2:
pt2 = [recognizer locationOfTouch:1 inView:recognizer.view];
case 1:
pt1 = [recognizer locationOfTouch:0 inView:recognizer.view];
}
switch (numTouches) {
case 3:
mid = CGPointMake( ( ( pt1.x + pt2.x ) / 2.0f + pt3.x ) / 2.0f, ( ( pt1.y + pt2.y ) / 2.0f + pt3.y ) / 2.0f );
break;
case 2:
mid = CGPointMake( ( pt1.x + pt2.x ) / 2.0f, ( pt1.y + pt2.y ) / 2.0f );
break;
case 1:
mid = CGPointMake( pt1.x, pt1.y);
break;
}
return mid;
}
#end
Hope it will help :) Cheers

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 ;)
}
}

UIView flipping by UIPanGestureRecognizer

I'm trying to use UIPanGestureRecognizer to flip an UIView. I'm using below code to handle flipping the view,
- (void)handlePan:(UIPanGestureRecognizer*)gesture{
CGPoint translation = [gesture translationInView:self.view];
NSLog(#"PAN X VALUE %f", translation.x );
double percentageOfWidth = translation.x / (gesture.view.frame.size.width / 2);
float angle = (percentageOfWidth * 100) * M_PI_2 / 180.0f;
CALayer *layer = testView.layer;
CATransform3D flipTransform = CATransform3DIdentity;
flipTransform.m34 = -0.002f;
flipTransform = CATransform3DRotate(flipTransform, angle, 0.0f, 1.0f, 0.0f);
layer.transform = flipTransform;
}
My problem is when i pan, sometimes there are some quick jumpings happen, I believe thats because translation.x(PAN X VALUE) value jumps from few points ahead, In my case i need it to be very smooth.
Any help greatly appreciated.
Thanks in advance.
You can use the gestureRecognizerShouldBegin method, which u can limit the UIPanGestureRecognizer sensitivity.
Example:
- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)panGestureRecognizer {
CGPoint translation = [panGestureRecognizer translationInView:self.view];
return fabs(translation.y) < fabs(translation.x);
}
Here's how I solved this for a cube rotation - just take the amount dragged and divide:
- (void)panHandle:(UIPanGestureRecognizer*)recognizer;
{
if ([recognizer state] == UIGestureRecognizerStateBegan)
{
CGPoint translation = [recognizer translationInView:[self superview]];
_startingX = translation.x;
}
else if ([recognizer state] == UIGestureRecognizerStateChanged)
{
CGPoint translation = [recognizer translationInView:[self superview]];
CGFloat angle = -(_startingX - translation.x) / 4;
//Now do translation with angle
_transitionContainer.layer.sublayerTransform = [self->_currentMetrics asTransformWithAngle:angle];
}
else if ([recognizer state] == UIGestureRecognizerStateEnded)
{
[self transitionOrReturnToOrigin];
}
}

Limit UIPanGestureRecognizer movement in circle

I am using UIPanGesturerecogniser to move a UIButton on the screen.
I am adding the gesture to the button in this way:
panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[ButtonNote addGestureRecognizer:panRecognizer];
and the method is
- (void)move:(id)sender {
[[[(UITapGestureRecognizer*)sender view] layer] removeAllAnimations];
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.ViewA];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
firstX = [[sender view] center].x;
firstY = [[sender view] center].y;
[self.view addSubview:[(UIPanGestureRecognizer*)sender view]];
if (self.Button1.frame.size.height > 200) {
}
else {
}
}
translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY+translatedPoint.y);
[[sender view] setCenter:translatedPoint];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded||[(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateCancelled||[(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateFailed){
CGPoint fingerPoint2 = [(UIPanGestureRecognizer*)sender locationInView:self.BallBin.superview];
if (CGRectContainsPoint(self.BallBin.frame, fingerPoint2)) {
if (self.Button3.frame.size.height > 200) {
UIPanGestureRecognizer *gesture = (UIPanGestureRecognizer *)sender;
UIButton *button = (UIButton *)gesture.view;
[[(UIPanGestureRecognizer*)sender view] removeFromSuperview];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *myFilePath = [documentsDirectoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#", button.titleLabel.text]];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:myFilePath error:NULL];
[self performSelector:#selector(DeleteBusinessCard:) withObject:nil afterDelay:0.5];
}
else {
[self.ViewA addSubview:[(UIPanGestureRecognizer*)sender view]];
}
}
if (self.Button1.frame.size.height > 200) {
}
else {
[self.ViewB addSubview:self.BallBin];
}
}];
}
CGFloat finalX = translatedPoint.x + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.ViewA].x);
CGFloat finalY = translatedPoint.y + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.ViewA].y);
if(UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
if(finalX < 0) {
finalX = 0;
}
else if(finalX > 768) {
finalX = 768;
}
if(finalY < 0) {
finalY = 0;
}
else if(finalY > 1024) {
finalY = 1024;
}
}
else {
if(finalX < 0) {
finalX = 0;
}
else if(finalX > 1024) {
finalX = 768;
}
if(finalY < 0) {
finalY = 0;
}
else if(finalY > 768) {
finalY = 1024;
}
}
}
}
I want to limit the movement of the button in a certain circle area on screen, for e.g. of radius 80. Now the button is moving all over the screen. Anyway ViewA is a UIView covering the whole screen.
Use Pitagoras Formula to calculate the distance between the current location and the start point. In your case:
if (gesture.state == UIGestureRecognizerStateChanged)
{
if (sqrt(deltaX*deltaX + deltaY*deltaY) < 80)
move view to finger's position
else
stay where you are
}
We can have a logic to calculate the coordination to a particular center.
When the Pan Gesture is happening, the function should modify the center of the panning object,
with example in the following code, the pannig object named pin, which is a 50x50 pts image,
will be set to get around a Large Circle image with 194x194 pts, located in 63, 141.
And this the PanGesture handler code:
- (void)pinPanPiece:(UIPanGestureRecognizer *)gestureRecognizer {
CGPoint center = CGPointMake(63.0 + 194.0/2, 141.0+ 194.0/2);
UIView *piece = [gestureRecognizer view];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
if (piece == pin) {
CGPoint translation = [gestureRecognizer translationInView:[piece superview]];
float newX = piece.frame.origin.x + translation.x;
CGRect newFrame = piece.frame;
CGPoint pinCenter = CGPointMake(newFrame.origin.x + newFrame.size.width / 2.0, newFrame.origin.y + newFrame.size.height / 2.0);
newFrame.origin.x = newX;
CGPoint newPinCenter = CGPointMake(newFrame.origin.x + newFrame.size.width / 2.0, newFrame.origin.y + newFrame.size.height / 2.0);
float detectY = pinCenter.y + translation.y;
BOOL bUpCenter = detectY < center.y;
float deltaX = center.x - newPinCenter.x;
float deltaY = sqrtf((97.0 *97.0) - (deltaX * deltaX));
float newY;
if (bUpCenter) {
newY = center.y - deltaY;
}
else {
newY = center.y + deltaY;
}
newY -= newFrame.size.height / 2.0;
newFrame.origin.y = newY;
if ((newPinCenter.x >= 63.0) && (newPinCenter.x <= 63.0+194.0)) {
[piece setFrame:newFrame];
}
}
[gestureRecognizer setTranslation:CGPointZero inView:[piece superview]];
}
}

Resources