UIImageView Jumps when Touch Event Occurs - ios

Okay basically what this code currently does is drag an image up and down along the Y axis depending on where the user drags it, and it returns to its original position. My problem is that if someone were to not touch directly on the center of the UIImageView and start dragging it would jolt (very not smooth). Wherever someone is touching the UIImageView and starts dragging the UIImageView jolts a little to go directly on the center of the touch event.
I was thinking about using animation just to move it where the image needs to go, or is there another way?
I apologize if this is an inefficient way to do this. I'm fairly new to the IOS world.
Here's what I have:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//Gets location of UIImageView.
self.originalFrame = self.foregroundImage.frame;
}
//This method is used for moving the UIImageView along the y axis depending on touch events.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if([touch view]==self.foregroundImage) {
CGPoint location = [touch locationInView:self.view];
location.x=self.foregroundImage.center.x;
self.foregroundImage.center=location;
}
}
//This method sets the UIImageView back to its original position.
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGRect newFrame = self.foregroundImage.frame;
newFrame.origin.y = self.originalFrame.origin.y;
[UIView animateWithDuration:1.1 animations:^{
self.foregroundImage.frame = newFrame;
}];
}

You also need to save the first location in touchesBegan, relative to the parent view. Then, you can use that to change the frame by the difference between the previous location and the new location. Please see the following code.
- (void) touchesBegan: (NSSet*) touches
withEvent: (UIEvent*) event
{
if (touches.count == 1)
{
UITouch* touch = [touches anyObject];
self.touchLocation = [touch locationInView: self.view];
}
}
- (void) touchesMoved: (NSSet*) touches
withEvent: (UIEvent*) event
{
if (touches.count == 1)
{
UITouch* touch = [touches anyObject];
CGPoint newTouchLocation = [touch locationInView: self.view];
if (touch.view == self.foregroundImage)
{
/* Determine the difference between the last touch locations */
CGFloat deltaX = newTouchLocation.x - self.touchLocation.x;
CGFloat deltaY = newTouchLocation.y - self.touchLocation.y;
/* Offset the foreground image */
self.foregroundImage.center
= CGPointMake(self.foregroundImage.center.x + deltaX,
self.foregroundImage.center.y + deltaY);
}
/* Keep track of the new touch location */
self.touchLocation = newTouchLocation;
}
}

Related

Sprite Kit: How to make a node "jump" and also move it left or right, dependant on node position and length of touch?

This is my first post so go easy haha.
I'm new to 'iOS' 'coding', 'Xcode' and 'spritekit'. I'm looking to make an image node "jump" a distance on the positive y-axis if I touch anywhere on the screen, although if I touch somewhere to the left or right if the image and hold for a certain time, it moves in the respective left or right direction, a distance respective to the length of the touch.
Not sure if that's very clear, but any help would be appreciated! Thanks!
You could move a node like this
In touchesEnded: or touchesBegan: method:
{
node.position.y += 50;
}
In order for sprite to move somewhere you could also use actions, there is a family of actions like moveTo action.
I would suggest picking upa tutorial or a book about sprite kit. Good site with free tutorials is raywenderlich.com
Please Try this code :
a sprite move : left/right according to your touch direction anywhere on screen
// CGPoint initialPos; // in .h file
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchPt = [touch locationInView:touch.view];
initialPos = [[CCDirector sharedDirector] convertToGL:touchPt];
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch=[touches anyObject];
CGPoint currentPos=[myTouch locationInView:[myTouch view]];
currentPos=[[CCDirector sharedDirector] convertToGL:currentPos];
float diffX = currentPos.x - initialPos.x;
float diffY = currentPos.y - initialPos.y;
CGPoint velocity = ccp(diffX, diffY);
initialPos = currentPos;
[Sprite setPosition:ccpAdd([SmileBall position], velocity)];
}
- (void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch=[touches anyObject];
CGPoint currentPos=[myTouch locationInView:[myTouch view]];
currentPos=[[CCDirector sharedDirector] convertToGL:currentPos];
float diffX = currentPos.x - initialPos.x;
float diffY = currentPos.y - initialPos.y;
CGPoint velocity = ccp(diffX, diffY);
initialPos = currentPos;
[Sprite setPosition:ccpAdd([SmileBall position], velocity)];
}
a sprite jump up: according to your touch on screen
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CCSprite *RunningChar;
RunningChar=(CCSprite *)[self getChildByTag:10];
UITouch *touch = [touches anyObject];
CGPoint touchPt = [touch locationInView:touch.view];
touchPt = [[CCDirector sharedDirector] convertToGL:touchPt];
float radian = ccpToAngle(ccpSub(touchPt, prevPoint));
float degrees = CC_RADIANS_TO_DEGREES(radian);
if (degrees >= 22.5 && degrees <= 112.5) // for upward direction :). otherwise you can write only code without ant condition
{
CCJumpTo *jump=[CCJumpTo actionWithDuration:0.7 position:CGPointMake(RunningChar.position.x, 87) height:110 jumps:1];
[RunningChar runAction:seq];
}
else
{
}
}
Try this :)

Find out, that the touch position is in Imageview

i try to run some code, when my finger is moved to the same position, where the imageview is.
I defined the position of the image view:
CGRect imagepos = myImage.frame;
And the position of actual touch position:
UITouch *myTouch = [[touches allObjects] objectAtIndex: 0];
CGPoint currentPos = [myTouch locationInView: self.view];
I tried withCGPointEqualToPoint it not worked. Then i tried with CGRectContainsPoint it also not worked, because, when imagepos and currentpos have the same x coordinates, my "some code" is running (my finger is not moved to the image, they had only the same x positions. Y positions are totally different).
How can I say, when my finger (also in the method touchesmoved) touch/is moved to/is at anywhere of the image, run some code or a method?
Thanks for Answers.
In your touchesBegan method, you can try something like this:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if([touch view] == myImgView)
{
NSLog(#"My Image was touched");
}
}
This tells you when your ImageView is touched. Make sure you set userInteractionEnabled to YES in your imageView.
Hey try out below -
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self]; //Now you got current location of click or tap
if(location.y == YOUR_IMAGE_VIEW_POSITION_Y)
{
NSLog(#"Got the TOUCH...OOOoopsss !!!");
}
}
}
Hope this helped.
There is a function...
CGRectContainsPoint(rect, point);
It returns a bool if the point is inside the rect.
So get the touch point and run this with the imageView frame to find out if the touch was inside the image view.

Sprite Kit detect position of touch

I want to run different actions depending on if you touch the left or right half of the screen. So an action when you touch the left half, and another when the right half is touched.
I suppose I could make a transparent button image that covers half of the screen and use this code to run an action when touched, but I don't think that's the way to go. Is there a better way to detect the position of a touch?
Override the touchesEnded:withEvent or touchesBegan:withEvent: method to do this:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
if(touch){
if([touch locationInView:self.view]>self.size.width/2){
[self runTouchOnRightSideAction];
}else{
[self runTouchOnLeftSideAction];
}
}
}
I came up with the following code and it works perfect.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
// If left half of the screen is touched
if (touchLocation.x < self.size.width / 2) {
// Do whatever..
}
// If right half of the screen is touched
if (touchLocation.x > self.size.width / 2) {
// Do whatever..
}
}

TouchesMoved with UITouch

I'm trying to create a simple application where you can move your UIImageView by touching him and dragging him around.
my UIImageView is called imv
-(void ) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch * touch = [touches anyObject];
if([touch view] == self.imv){
CGPoint location = [touch locationInView:self.view];
self.imv.center = location;
}
}
-(void ) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch * touch = [touches anyObject];
if([touch view] == self.imv){
CGPoint location = [touch locationInView:self.view];
self.imv.center = location;
}
}
i'am trying to solve this like whole day and i don't know what is wrong. If i disable if statement it's working else not. What can i do?
Thanks for the answers
Unless you've subclassed UIImageView (unlikely), your view is receiving the touch events.
These days it's simpler & more usual to use a UIGestureRecognizer for this kind of thing, in this case a UIPanGestureRecognizer.
e.g.
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(dragImageView:)];
[self.imv addGestureRecognizer:pan];
- (void)dragImageView:(UIPanGestureRecognizer *)dragImageView {
if(UIGestureRecognizerStateBegan == state) {
originalCenter = self.imv.center; // add CGPoint originalCenter; member
} else if(UIGestureRecognizerStateChanged == state) {
CGPoint translate = [pan translationInView:self.imv.superview];
self.imv.center = CGPointMake(originalCenter.x + translate.x, originalCenter.y + translate.y);
}
}
From a bit of experimenting, it seems that the [touch view] is returning the main UIView and not your subview, hence the problem with the if statement not working (I added the UIImageView in a storyboard xib). EDIT- it's because UIImageViews don't handle touch events by default - see here . When adding a regular UIView in the viewDidLoad seems to work as you would expect.
Anyway, this adapted version of your code works for me
-(void)moveImageForTouches:(NSSet*)touches
{
UITouch * touch = [touches anyObject];
CGPoint location = [touch locationInView:self.view];
if(CGRectContainsPoint(self.imv.frame, location))
{
self.imv.center = location;
}
}
-(void ) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self moveImageForTouches:touches];
}
-(void ) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self moveImageForTouches:touches];
}

How to drag an image view after applying CGAffineTransformMakeRotation

I am developing an app, Which has feature that dragging and rotating the image view.
I have implemented to drag and rotate successfully by using below code
In touchesBegan Method
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
touchStart = [[touches anyObject] locationInView:imageView];
isResizingLR = (containerVw.bounds.size.width - touchStart.x < kResizeThumbSize && containerVw.bounds.size.height - touchStart.y < kResizeThumbSize);
}
In touchesMoved Method
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
CGPoint touchPoint = [[touches anyObject] locationInView:containerVw];
CGPoint previous=[[touches anyObject]previousLocationInView:containerVw];
UITouch *touch = [[event allTouches] anyObject];
if (isResizingLR) {
CGFloat currA = [self pointToAngleFromCenter:[touch locationInView:containerVw.superview]] ;
CGFloat prevA = [self pointToAngleFromCenter:[touch previousLocationInView:containerVw.superview]] ;
// the current value of the rotation angle
CGFloat tranA = atan2(containerVw.transform.b, containerVw.transform.a) ;
// the angle difference between last touch and the current touch
CGFloat diffA = currA - prevA ;
// the new angle resulting from applying the difference
CGFloat angle1 = tranA - diffA ;
CGAffineTransform t = CGAffineTransformMakeRotation(angle1) ;
containerVw.transform =t;
}
if (!isResizingLR) {
containerVw.center = CGPointMake(containerVw.center.x + touchPoint.x - touchStart.x, containerVw.center.y + touchPoint.y - touchStart.y);
}
}
My Problem
Above code is working fine until rotating the image view after dragging. In case if i drag the image view after rotating it. image view has gone away from screen.
In touchesEnd method i tried to print the image view frame. for example my image view frame at the beginning is (100,100,150,149) after rotating it the image view 160ยบ frame has changed to (103,31,182,183) up to now its working fine.
After rotating it if try to move an image view, the image view has gone away from screen now the frame has changed to (615,-212,182,183)
Please guide me how do i resolve it.
Have a look at this project. This may help you. But here, the movement is handled by gestures and not by touch. It may solve your problem.

Resources