iOS route-me draggable marker looses track (even in samples) - ios

In my iOS app I'm using the route me lib to display a map in offline mode.
I have some markers on the map, and now I would like to make them draggable. I used this code :
- (void) mapView:(RMMapView *)map didDragMarker:(HotspotMarker*)marker withEvent:(UIEvent *)event
{
UITouch* touch = [[event allTouches] anyObject];
if([[event allTouches] count] == 1 && touch.phase == UITouchPhaseMoved)
{
CGPoint position = [touch locationInView:[touch.view superview]];
CGSize delta = CGSizeMake((position.x-(marker.position.x)),
(position.y-(marker.position.y)));
[marker moveBy: delta];
[marker setProjectedLocation:[[_mapView.contents projection]
latLongToPoint:[_mapView pixelToLatLong:marker.position]]];
}
}
The markers drag well when I move the mouse slowly, but when I move the mouse a little quickly, I loose the track.
So I looked the sample "MapTestbedFlipMaps" project and run it... And encountered the same problem.
Then I tried to do it by myself with a gesture recognizer... but I still have the issue.
Any idea ?
EDIT : the problem doesn't come from the marker's image's size, I tried with a 100x100 image and got the same result.

Try This:
- (void) mapView:(RMMapView *)map didDragMarker:(RMMarker *)marker withEvent:(UIEvent *)event
{
CGPoint position = [[[event allTouches] anyObject] locationInView:mapView];
CGRect rect = [marker bounds];
[self.mapView.markerManager moveMarker:marker AtXY:CGPointMake(position.x,position.y +rect.size.height/3)];
}

Related

TouchesMoved only moves a little

I am trying to allow the user to drag a label around the screen, but in the simulator it only moves a little each time I touch somewhere on the screen. It will jump to the location and then drag slightly, but then it will stop dragging and I have to touch a different location to get it to move again. Here is my code in my .m file.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *Drag = [[event allTouches] anyObject];
firstInitial.center = [Drag locationInView: self.view];
}
My ultimate goal is to be able to drag three different labels on the screen, but I'm just trying to tackle this problem first. I would greatly appreciate any help!
Thanks.
Try using a UIGestureRecognizer instead of -touchesMoved:withEvent:. And implementing something similar to the following code.
//Inside viewDidLoad
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(dragonMoved:)];
panGesture.minimumNumberOfTouches = 1;
[self addGestureRecognizer:panGesture];
//**********
- (void)dragonMoved:(UIPanGestureRecognizer *)gesture{
CGPoint touchLocation = [gesture locationInView:self];
static UIView *currentDragObject;
if(UIGestureRecognizerStateBegan == gesture.state){
for(DragObect *dragView in self.dragObjects){
if(CGRectContainsPoint(dragView.frame, touchLocation)){
currentDragObject = dragView;
break;
}
}
}else if(UIGestureRecognizerStateChanged == gesture.state){
currentDragObject.center = touchLocation;
}else if (UIGestureRecognizerStateEnded == gesture.state){
currentDragObject = nil;
}
}

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.

Scaling custom UIView by CGAffineTransformMakeScale breaks dragging with touchesMoved

I have prepared and checked into GitHub a simple test case for dragging custom UIView:
It works well and dragging is implemented in the Tile.m as:
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
CGPoint previous = [touch previousLocationInView:self];
self.frame = CGRectOffset(self.frame,
(location.x - previous.x),
(location.y - previous.y));
}
However the tiles are too large for my actual game (and I will have to adjust their scaling once the game board in UIScrollView is zoomed anyway):
So I scale my custom UIViews down by calling
tile.transform = CGAffineTransformMakeScale(.5, .5);
The size changes, but the tiles are suddenly dragged "twice as quickly" as needed:
Probably the touchesMoved code (s. above) should be adjusted, but I'm not sure what has been broken there by the transform manipulation?
Nevermind, I have found the solution:
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
CGPoint previous = [touch previousLocationInView:self];
if (!CGAffineTransformIsIdentity(self.transform)) {
location = CGPointApplyAffineTransform(location, self.transform);
previous = CGPointApplyAffineTransform(previous, self.transform);
}
self.frame = CGRectOffset(self.frame,
(location.x - previous.x),
(location.y - previous.y));
}

UIImageView Jumps when Touch Event Occurs

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

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