I am using these methods and these variables
CGPoint touchBegan;
CGPoint touchEnd;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
}
But I can not get the distance between two points. For example draw a line with your finger and get the distance between a CGPoint touchBegan and CGPoint touchEnd
Any help is appreciated thanks
It doesn't seem to exist any method or function that do this directly, you must take the difference of the two points coordinates and use pythagorean theorem:
CGPoint touchBegan;
CGPoint touchEnd;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch* touch= [touches anyObject];
touchBegan= [touch locationInView: self.view];
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch= [touches anyObject];
touchEnd= [touch locationInView: self.view];
CGFloat dx= touchBegan.x - touchEnd.x;
CGFloat dy= touchBegan.y - touchEnd.y;
CGFloat distance= sqrt(dx*dx + dy*dy);
< Do stuff with distance >
}
Just implement your own rendition of the Pythagorean theorem. For example:
CGPoint translation = CGPointMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y);
CGFloat distance = sqrtf(translation.x * translation.x + translation.y * translation.y);
Or, better, as Rob Mayoff pointed out, use the Math.h hypotf method:
CGFloat distance = hypotf(translation.x, translation.y);
Related
I am trying to make a sprite rotate with one finger touch. Honestly, i have no idea how to do it, new to spriteKit.
Any ideas?
This would rotate the sprite to where you touch using an action. If you'd want it to rotate while dragging the finger. You should remove the action and do the calculation on the touchesMoved: instead.
-(void)didMoveToView:(SKView *)view {
sprite = [SKSpriteNode spriteNodeWithImageNamed:#"Spaceship"];
sprite.xScale = 0.5;
sprite.yScale = 0.5;
sprite.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height/2);
[self addChild:sprite];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
float dY = sprite.position.y - location.y;
float dX = sprite.position.x - location.x;
float angle = atan2f(dY, dX) + 1.571f;
[sprite runAction:[SKAction rotateToAngle:angle duration:0.5 shortestUnitArc:YES]];
return;
}
}
Alternatively: (Remember to remove the code from the touchesBegan:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
float dY = sprite.position.y - location.y;
float dX = sprite.position.x - location.x;
float angle = (atan2f(dY, dX)) + 1.571f;
sprite.zRotation = angle;
}
}
This is what I have so far
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
for (UIImageView *imageView in _imageViewArray) {
CGPoint Location = [touch locationInView:touch.view];
imageView.center = Location;
}
}
The problem I am facing is when I move one image they all jump to the same place.
Thanks to cyberpawn this it what I did it get it to work
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint oldPoint = [touch previousLocationInView:touch.view];
CGPoint newPoint = [touch locationInView:touch.view];
CGPoint diff = CGPointMake(newPoint.x - oldPoint.x, newPoint.y - oldPoint.y);
for (UIImageView *imageView in _imageViewArray) {
if (CGRectContainsPoint(imageView.frame, newPoint)) {
CGPoint cntr = [imageView center];
[imageView setCenter:CGPointMake(cntr.x + diff.x, cntr.y + diff.y)];
}
}
}
Thats because you are moving them all to same location, you need to calculate the difference between touch locations and add that displacement to all views. Below code should solve your problem! Forget touchesBegan and Just override touchesMoved method like that.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint oldPoint = [touch previousLocationInView:touch.view];
CGPoint newPoint = [touch locationInView:touch.view];
CGPoint diff = CGPointMake(newPoint.x - oldPoint.x, newPoint.y - oldPoint.y);
for (UIImageView *imageView in _imageViewArray) {
CGPoint cntr = [imageView center];
[imageView setCenter:CGPointMake(cntr.x + diff.x, cntr.y + diff.y)];
}
}
If You want to move them separately when any of them is clicked than use below code instead!
float oldX, oldY;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint pt = [touch locationInView:touch.view];
for (UIImageView *imageView in _imageViewArray) {
if(CGRectContainsPoint(imageView.frame, pt)) {
oldX = imageView.center.x - imageView.frame.origin.x - pt.x;
oldY = imageView.center.y - imageView.frame.origin.y - pt.y;
break;
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint pt = [touch locationInView:touch.view];
for (UIImageView *imageView in _imageViewArray) {
if (CGRectContainsPoint(imageView.frame, pt)) {
[self setCenter:CGPointMake(pt.x+oldX, pt.y+oldY)];
}
}
Enjoy Programming!
Here you coded like that only. If you want to move a single image, then you have to find that image and you should move that image alone.
I've created a 200x200 circle in a custom UIView. I am using the following script to move the view object around the screen on the iPad.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
if([touch view] == newShape)
{
newShape.center = currentPoint;
}
[self.view setNeedsDisplay];
}
Everything works fine, I can move the circle anywhere on the screen. However, if I don't touch dead center on the circle object, it jumps slightly. By reading the code, this is quite obvious because newShape.center is being set to wherever the touch happens and ultimately snapping quickly to that position.
I'm looking for a way to move an object without snapping to the touch position. I'm thinking I would use xy coordinates to achieve this, but I'm not sure how to implement it.
Thanks!
Declare CGPoint prevPos; in .h file.
Here my view is _rectView.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
prevPos = currentPoint;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
if([touch view] == _rectView)
{
float delX = currentPoint.x - prevPos.x;
float delY = currentPoint.y - prevPos.y;
CGPoint np = CGPointMake(_rectView.frame.origin.x+delX, _rectView.frame.origin.y+delY);
//_rect.center = np;
CGRect fr = _rectView.frame;
fr.origin = np;
_rectView.frame = fr;
}
//[self.view setNeedsDisplay];
prevPos = currentPoint;
}
Use the above code. You will not get that 'jump' effect.
An obvious way to do it is to store the offset of the touch from the shape's center in -touchesBegan:withEvent: and apply the offset in -touchesMoved:withEvent:.
I have a UIImageView that is an arrow image. I added this view to a parent view with a frame of 500x500 dimensions. I want to rotate the UIImageView so that the arrow is always pointing to the center of its parent when the user touches and moves it around.
I was looking into CGAffineTransform and trigonometry rotations, but I'm having trouble getting started. Can anyone provide some insight?
Thanks!
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
pointerView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"pointer.png"]];
pointerView.layer.anchorPoint = CGPointMake(0, 0.5);
pointerView.center = point;
[self setPointerRotation];
[self addSubview:pointerView];
[pointerView release];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
pointerView.center = point;
[self setPointerRotation];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[pointerView removeFromSuperview];
pointerView = nil;
}
- (void)setPointerRotation {
CGAffineTransform transform = // calculate rotation so that pointerView points to the center of the superview
pointerView.transform = transform;
}
I was wondering how to draw a CGRect onto an UIImageView. Here is the code I've got but it doesn't seem to be working. Any suggestions? touch1 and touch2 are both CGPoints and point is a CGRect.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
touch1 = [touch locationInView:self];
touch2 = [touch locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
touch2 = [touch locationInView:self];
point = CGRectMake(touch2.x, touch2.y, 50, 50);
[self setNeedsDisplay];
}
- (void) drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetFillColorWithColor(context, pointColor.CGColor);
CGContextAddEllipseInRect(context, point);
CGContextDrawPath(context, kCGPathFillStroke);
}
What do you see actually happening?
A few notes:
You shouldn't be doing this with a UIImageView-- those are specifically intended to be containers for image files. You should just use a subclass of a regular UIView for this.
In your touchesBegan, you know that touch1 and touch2 will always be set to the same thing, right? You don't seem to ever be using touch1.
point is a misleading variable name for something that is a rect.
Your drawRect is not unreasonable. What is pointColor? If you're drawing black-on-black that might be part of the problem.
Listing 3-1 Code that creates an ellipse by applying a transform to a circle
CGContextScaleCTM(context, 1,2);
CGContextBeginPath(context);
CGContextAddArc(context, 0, 0, 25, 0, 2*M_PI, false);
CGContextStrokePath(context);
Lots more example code in the Quartz2d Example
I took your code only, its working for me. Just have look at it. And thanks for your code. In this sample i am drawing a rect.
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextAddRect(context, rectFrame);
CGContextDrawPath(context, kCGPathFillStroke);
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
startPoint = [touch locationInView:self];
rectFrame.origin.x = startPoint.x;
rectFrame.origin.y = startPoint.y;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
endPoint = [touch locationInView:self];
rectFrame.size.width = endPoint.y - startPoint.x;
rectFrame.size.height = endPoint.y - startPoint.x;
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
endPoint = [touch locationInView:self];
rectFrame.size.width = endPoint.y - startPoint.x;
rectFrame.size.height = endPoint.y - startPoint.x;
[self setNeedsDisplay];
}