I've got it so far that I can move, scale and rotate all the objects, but the multiple objects all move together. I want them to move seperate. I guess I have to change the objectatIndex to 1, but it just crashes.
I've used the following code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSArray *allTouches = [touches allObjects];
UITouch* t;
if([[event allTouches] count]==1){
if (CGRectContainsPoint([Birdie frame], [[allTouches objectAtIndex:0] locationInView:theimageView]) && CGRectContainsPoint([imageViewauto frame], [[allTouches objectAtIndex:0] locationInView:theimageView])) {
t=[[[event allTouches] allObjects] objectAtIndex:0];
touch1=[t locationInView:nil];
}
}else{
t=[[[event allTouches] allObjects] objectAtIndex:0];
touch1=[t locationInView:nil];
t=[[[event allTouches] allObjects] objectAtIndex:1];
touch2=[t locationInView:nil];
}
}
-(double)distance:(CGPoint)point1 toPoint:(CGPoint)point2
{
double deltaX, deltaY;
deltaX = point1.x - point2.x;
deltaY = point1.y - point2.y;
return sqrt(deltaX * deltaX + deltaY * deltaY);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint currentTouch1;
CGPoint currentTouch2;
NSArray *allTouches = [touches allObjects];
UITouch* t;
float scale,rotation;
if([[event allTouches] count]==1){
t=[[[event allTouches] allObjects] objectAtIndex:0];
if (CGRectContainsPoint([Birdie frame], [[allTouches objectAtIndex:0] locationInView:theimageView]) && CGRectContainsPoint([imageViewauto frame], [[allTouches objectAtIndex:0] locationInView:theimageView]))
{
touch2=[t locationInView:nil];
Birdie.center=CGPointMake(Birdie.center.x+touch2.x-touch1.x,Birdie.center.y+touch2.y-touch1.y);
imageViewauto.center=CGPointMake(imageViewauto.center.x+touch2.x-touch1.x,imageViewauto.center.y+touch2.y-touch1.y);
touch1=touch2;
}
}
else if([[event allTouches] count]==2)
{
t=[[[event allTouches] allObjects] objectAtIndex:0];
currentTouch1=[t locationInView:nil];
t=[[[event allTouches] allObjects] objectAtIndex:1];
currentTouch2=[t locationInView:nil];
double distance1 = [self distance:currentTouch1 toPoint:currentTouch2];
double distance2 = [self distance:touch1 toPoint:touch2];
if (distance2 == 0)
{
//handle the case where distance is zero
}
else {
scale =distance1 / distance2;}
rotation=atan2(currentTouch2.y-currentTouch1.y, currentTouch2.x-currentTouch1.x)-atan2(touch2.y-touch1.y,touch2.x-touch1.x);
if(isnan(scale)){
scale=1.0f;
}
NSLog(#"rotation %f",rotation);
NSLog(#"scale %f",scale);
if (CGRectContainsPoint([Birdie frame], [[allTouches objectAtIndex:0] locationInView:theimageView]) && CGRectContainsPoint([imageViewauto frame], [[allTouches objectAtIndex:0] locationInView:theimageView]))
{
Birdie.transform=CGAffineTransformScale(Birdie.transform, scale,scale);
Birdie.transform=CGAffineTransformRotate(Birdie.transform, rotation);
imageViewauto.transform=CGAffineTransformScale(imageViewauto.transform, scale,scale);
imageViewauto.transform=CGAffineTransformRotate(imageViewauto.transform, rotation);
}
else // In case of scaling or rotating the background imageView
{
imageView.transform=CGAffineTransformScale(imageView.transform, scale,scale);
imageView.transform=CGAffineTransformRotate(imageView.transform, rotation);
}
touch1=currentTouch1;
touch2=currentTouch2;
}
}
First of all, an easy way to handle drag, scale and rotate is to use GestureRecognizers like the bellow one:
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[self.view addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[self.view addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[self.view addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[self.view addGestureRecognizer:tapRecognizer];
To handle multiple UIImageViews you may use the position of touched points, you can use the bellow functions to do so:
- (CGPoint)locationInView:(UIView*)view;
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView*)view;
According to the number of touched you can use either the first or second function, and then see if the touched point is inside the frame of considered UIImageView, for example for scaling you can do as what is show in bellow:
-(void)scale:(id)sender {
UIView * pinchView = [(UIPinchGestureRecognizer*)sender view];
CGPoint first_point = [sender locationOfTouch:0 inView:pinchView];
CGPoint second_point = [sender locationOfTouch:1 inView:pinchView];
if (CGRectContainsPoint(my_image_view.frame, first_point) && CGRectContainsPoint(my_image_view.frame, second_point)) {
[self.view bringSubviewToFront:pinchView];
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = my_image_view.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[my_image_view setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];}}
its working
-(void)scale:(id)sender {
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
_lastScale = 1.0;
}
CGFloat scale = 1.0 - (_lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = self.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[self setTransform:newTransform];
_lastScale = [(UIPinchGestureRecognizer*)sender scale];
[self showOverlayWithFrame:self.frame];
}
-(void)rotate:(id)sender {
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
_lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (_lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = self.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[self setTransform:newTransform];
_lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
[self showOverlayWithFrame:self.frame];
}
-(void)move:(id)sender {
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
_firstX = [self center].x;
_firstY = [self center].y;
}
translatedPoint = CGPointMake(_firstX+translatedPoint.x, _firstY+translatedPoint.y);
[self setCenter:translatedPoint];
[self showOverlayWithFrame:self.frame];
NSLog(#"after move x= %f y=%f " , _firstX,_firstY);
}
Related
I have to perform all the gesture on my imageview at a time, means user can move imageview on single tap at a time on double tap also zooming and rotation possible.Now i am found this methods to perform multiple gesture but unable to perform zoom and roation.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
Before i am applied UIPinchGestureRecognizer,UIRotationGestureRecognizer and UIPanGestureRecognizer but it handle only one gesture at a time.Please help me to solve this or give me any other better option if possible.
UIPinchGestureRecognizer *pinchGesture = ... //initialize
pinchGesture.delegate = self;
//same for rotation gesture
//and then implement delegate method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
Set the gesture like this.
self.view.multipleTouchEnabled=YES;
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveViewWithGestureRecognizer:)];
panGestureRecognizer.delegate=self;
[self.sub_View addGestureRecognizer:panGestureRecognizer];
UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(handleRotationWithGestureRecognizer:)];
rotationGestureRecognizer.delegate=self;
[self.sub_View addGestureRecognizer:rotationGestureRecognizer];
UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(handlePinchWithGestureRecognizer:)];
pinchGestureRecognizer.delegate=self;
[self.sub_View addGestureRecognizer:pinchGestureRecognizer];
[self.imageView setUserInteractionEnabled:YES];
Handle the action
-(void)handlePinchWithGestureRecognizer:(UIPinchGestureRecognizer *)pinchGestureRecognizer{
[self.superImage_View setAlpha:0.5];
if (pinchGestureRecognizer.state == UIGestureRecognizerStateEnded) {
[self.superImage_View setAlpha:1.0];
}
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, pinchGestureRecognizer.scale, pinchGestureRecognizer.scale);
pinchGestureRecognizer.scale =1.0;
}
-(void)handleRotationWithGestureRecognizer:(UIRotationGestureRecognizer *)rotationGestureRecognizer{
[self.superImage_View setAlpha:0.5];
if (rotationGestureRecognizer.state == UIGestureRecognizerStateEnded) {
[self.superImage_View setAlpha:1.0];
}
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, rotationGestureRecognizer.rotation);
rotationGestureRecognizer.rotation = 0.0;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
-(void)moveViewWithGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognizer{
//CGPoint touchLocation = [panGestureRecognizer locationInView:self.sub_View];
// self.imageView.center = touchLocation;
[self.superImage_View setAlpha:0.5];
CGPoint translation = [panGestureRecognizer translationInView:self.view];
self.imageView.center = CGPointMake(self.imageView.center.x + translation.x,
self.imageView.center.y + translation.y);
[panGestureRecognizer setTranslation:CGPointMake(0, 0) inView:self.view];
if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [panGestureRecognizer 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(self.imageView.center.x + (velocity.x * slideFactor),
self.imageView.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:^{
self.imageView.center = finalPoint;
} completion:nil];
[self.superImage_View setAlpha:1.0];
}
}
I was adding multiple gestures in one view, The view have a one close button at corner of the view, Everything is working fine but when I am zoom that view close button was also zoom with that view, Now I want to zoom only that view not that close button, Please suggest me How to do this ?
see below image for reference.
Code for pinch Zoom
-(void)addStickersWithView:(UIView*)view image:(UIImage*)image{
CGPoint center = self.imgPhoto.center;
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotatePiece:)];
[imgView setContentMode:UIViewContentModeScaleToFill];
UIView *viewZoom = [[UIView alloc] initWithFrame:CGRectMake(center.x-45,center.y-45, 90, 90)];
// [viewZoom setBackgroundColor:[UIColor redColor]];
imgView.frame = CGRectMake(5, 5, CGRectGetWidth(viewZoom.frame)-10, CGRectGetHeight(viewZoom.frame)-10);
[viewZoom addSubview:imgView];
[viewZoom addGestureRecognizer:rotationGesture];
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scalePiece:)];
[pinchGesture setDelegate:self];
[viewZoom addGestureRecognizer:pinchGesture];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveImage:)];
[panGesture setMinimumNumberOfTouches:1];
[panGesture setMaximumNumberOfTouches:1];
[viewZoom addGestureRecognizer:panGesture];
UIButton *btnCloseSticker = [UIButton buttonWithType:UIButtonTypeCustom];
[btnCloseSticker setBounds:CGRectMake(0, 0, 30,30)];
[btnCloseSticker setImage:[UIImage imageNamed:#"close1.png"] forState:UIControlStateNormal];
[btnCloseSticker addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
self.stickerCount++;
btnCloseSticker.tag = self.stickerCount;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(TapToShowClose:)];
tapGesture.numberOfTapsRequired = 2;
[viewZoom addGestureRecognizer:tapGesture];
viewZoom.layer.borderColor = [UIColor whiteColor].CGColor;
viewZoom.layer.borderWidth = 3.0;
viewZoom.tag = self.stickerCount+kTagBorder;
[viewZoom addSubview:btnCloseSticker];
[view addSubview:viewZoom];
}
-(void)hideShowBorderCloseButton{
int borderCount = self.stickerCount-kTagBorder;
for(int i=1;i<=borderCount;i++){
UIView *view = [self.viewStickers viewWithTag:i+kTagBorder];
UIView *view1 = [self.viewStickers viewWithTag:i+(kTagBorder*2)];
view.hidden = YES;
view1.layer.borderWidth = 0.0;
}
}
-(void)buttonPressed:(id)sender{
UIView *view = [sender superview];
[view removeFromSuperview];
self.stickerCount--;
}
- (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [gestureRecognizer scale];
}
UIButton *btn = [self.viewStickers viewWithTag:gestureRecognizer.view.tag-kTagBorder];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:#"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 3.0;
const CGFloat kMinScale = 1.0;
CGFloat newScale = 1 - (lastScale - [gestureRecognizer scale]);
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
[gestureRecognizer view].transform = transform;
lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
-(void)TapToShowClose:(UITapGestureRecognizer *)gestureRecognizer{
//int borderCount = self.stickerCount-kTagBorder;
UIView *view = gestureRecognizer.view; //cast pointer to the derived class if needed
view.layer.borderWidth = 2.0;
UIView *view1 = [self.viewStickers viewWithTag:view.tag-kTagBorder];
[(UIButton*)view1 setImage:[UIImage imageNamed:#"close1.png"] forState:UIControlStateNormal];
[view1 setBounds:CGRectMake(0, 0, 30,30)];
view1.hidden = NO;
}
- (void)moveImage:(UIPanGestureRecognizer *)recognizer
{
CGPoint newCenter = [recognizer translationInView:self.view];
[self hideShowBorderCloseButton];
if([recognizer state] == UIGestureRecognizerStateBegan) {
beginX = recognizer.view.center.x;
beginY = recognizer.view.center.y;
}
newCenter = CGPointMake(beginX + newCenter.x, beginY + newCenter.y);
[recognizer.view setCenter:newCenter];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
// if the gesture recognizers are on different views, don't allow simultaneous recognition
if (gestureRecognizer.view != otherGestureRecognizer.view)
return NO;
// if either of the gesture recognizers is the long press, don't allow simultaneous recognition
if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] || [otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]])
return NO;
return YES;
}
- (void)rotatePiece:(UIRotationGestureRecognizer *)gestureRecognizer {
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
[self hideShowBorderCloseButton];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
[gestureRecognizer view].transform = CGAffineTransformRotate([[gestureRecognizer view] transform], [gestureRecognizer rotation]);
[gestureRecognizer setRotation:0];
}
}
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
[self hideShowBorderCloseButton];
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
UIView *piece = gestureRecognizer.view;
CGPoint locationInView = [gestureRecognizer locationInView:piece];
CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];
piece.layer.anchorPoint = CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height);
piece.center = locationInSuperview;
}
}
In place of scaling view. it's batter to calculate the frame with your zoom level. and update the frame of the view. check out the below method.
- (IBAction)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [gestureRecognizer scale];
}
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat newScale = 1 - (lastScale - [gestureRecognizer scale]);
[self changeScale:newScale];
lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
-(void)changeScale :(float)newScale{
CGAffineTransform transform = CGAffineTransformScale([viewForpinch transform], newScale, newScale);
viewForpinch.transform = transform;
float scale = viewForpinch.transform.a;
float buttonScale = 1 / scale;
btnl.transform= CGAffineTransformScale(CGAffineTransformIdentity, buttonScale, buttonScale);
}
The easy way to do it is to remove the close button from that view, and add it on top of the view you're zooming with a different view.
You can use. insertSubview:aboveSubview:
I want to crop an UIImageView in rectangular size and it Should be resizable, Please anyone help me, I am struggling.
You can use below code to add pan gesture from which you can move the imageview and pinch gesture through which you can resize the image
-(void)addGesture {
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[imgView addGestureRecognizer:panRecognizer];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(resize:)];
[imgView addGestureRecognizer:pinchRecognizer];
}
-(void)move:(id)sender {
[self.view bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
if ([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
firstX = [[sender view] center].x;
firstY = [[sender view] center].y;
}
translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY);
[[sender view] setCenter:translatedPoint];
}
- (void)resize:(UIPinchGestureRecognizer *)recognizer
{
if([recognizer state] == UIGestureRecognizerStateBegan) {
_lastScale = 1.0;
if ([recognizer numberOfTouches] >= 2) { //should always be true when using a PinchGR
CGPoint touch1 = [recognizer locationOfTouch:0 inView:self.imageForEditing];
CGPoint touch2 = [recognizer locationOfTouch:1 inView:self.imageForEditing];
CGPoint mid;
mid.x = ((touch2.x - touch1.x) / 2) + touch1.x;
mid.y = ((touch2.y - touch1.y) / 2) + touch1.y;
CGSize imageViewSize = self.imageForEditing.frame.size;
CGPoint anchor;
anchor.x = mid.x / imageViewSize.width;
anchor.y = mid.y / imageViewSize.height;
self.imageForEditing.layer.anchorPoint = anchor;
}
}
CGFloat scale = 1.0 - (_lastScale - [recognizer scale]);
CGAffineTransform currentTransform = self.imageForEditing.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[self.imageForEditing setTransform:newTransform];
_lastScale = [recognizer scale];
}
I have a scene with one sprite, the image used for the sprites is an oval.
The problem I'm facing is that, whenever I use touchAtPoint it returns the sprite even if the touch occurs at a transparent area of the image.
How can I solve that?
My current code looks like:
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.backgroundColor = [SKColor blackColor];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:#"Red"];
sprite.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:50.0];
sprite.physicsBody.affectedByGravity = NO;
sprite.physicsBody.usesPreciseCollisionDetection = YES;
[self addChild: sprite];
}
return self;
}
- (void)didMoveToView:(SKView *)view {
UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanFrom:)];
[self.view addGestureRecognizer:gestureRecognizer];
}
- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
CGPoint touchLocation = [recognizer locationInView:recognizer.view];
touchLocation = [self convertPointFromView:touchLocation];
SKNode *touchedNode = (SKNode *)[self nodeAtPoint:touchLocation];
_selectedNode = touchedNode;
}
else if (recognizer.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [recognizer translationInView:recognizer.view];
translation = CGPointMake(translation.x, -translation.y);
[self panForTranslation:translation];
[recognizer setTranslation:CGPointZero inView:recognizer.view];
}
}
- (void)panForTranslation:(CGPoint)translation {
CGPoint position = [_selectedNode position];
[_selectedNode setPosition:CGPointMake(position.x + translation.x, position.y + translation.y)];
}
OK, so the only relevant code here is...
CGPoint touchLocation = [recognizer locationInView:recognizer.view];
touchLocation = [self convertPointFromView:touchLocation];
SKNode *touchedNode = (SKNode *)[self nodeAtPoint:touchLocation];
_selectedNode = touchedNode;
This needs to change to something like this...
CGPoint touchLocation = [recognizer locationInView:recognizer.view];
touchLocation = [self convertPointFromView:touchLocation];
SKNode *touchedNode = (SKNode *)[self nodeAtPoint:touchLocation];
// Work out if the touch is inside the circle
CGPoint centerOfNode = CGPointMake(touchedNode.position.x + touchedNode.size.width * 0.5, touchedNode.positiony + touchedNode.size.height * 0.5);
CGFloat dx = touchedNode.position.x - touchLocation.x;
CGFloat dy = touchedNode.position.y - touchLocation.y;
CGFloat distanceFromCenter = sqrtf(dx * dx + dy * dy);
if (distanceFromCenter <= touchedNode.size.width * 0.5) {
_selectedNode = touchedNode;
}
I am trying to rotate a view , with UIRotationGestureRecognizer but the problem is the rotation's angle is not center of my view !! here is my code :
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[self.view addGestureRecognizer:rotationRecognizer];
-(void)rotate:(id)sender {
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
_lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (_lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = textViews.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
_lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
[textViews setTransform:newTransform];
}
// create and configure the rotation gesture
UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotationGestureDetected:)];
[rotationGestureRecognizer setDelegate:self];
[YOUR_OBJECT_HERE addGestureRecognizer:rotationGestureRecognizer];
// YOUR_OBJECT_HERE - can be any object that you want to rotate (e.g. textView as in your case)
- (void)rotationGestureDetected:(UIRotationGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat rotation = [recognizer rotation];
[recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, rotation)];
[recognizer setRotation:0];
}
}