Translate uiview in direction of touch moved, iphone - ios

I want to translate UIView in same direction as touch moves .
Please suggest.

Modify the touchesBegan and touchesMoved methods to be like the following
float oldX, oldY;
BOOL dragging;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if (CGRectContainsPoint(window.frame, touchLocation)) {
dragging = YES;
oldX = touchLocation.x;
oldY = touchLocation.y;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if (dragging) {
CGRect frame = window.frame;
frame.origin.x = window.frame.origin.x + touchLocation.x - oldX;
frame.origin.y = window.frame.origin.y + touchLocation.y - oldY;
window.frame = frame;
}
oldX = touchLocation.x;
oldY = touchLocation.y;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
dragging = NO;
}
Hope it help

Try to do like the code below. I'm not sure if it is a best solution for all direction translation.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] != 1) return;
_swipeStartInX = [[touches anyObject] locationInView:self].x;
_swipeStartInY = [[touches anyObject] locationInView:self].y;
_swiping = YES;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!_swiping || [touches count] != 1) return;
CGFloat swipeDistanceInX = [[touches anyObject] locationInView:self].x - _swipeStartInX;
CGFloat swipeDistanceInY = [[touches anyObject] locationInView:self].y - _swipeStartInY;
CGSize contentSize = self.frame.size;
[_yourView setFrame:CGRectMake(swipeDistanceInX - contentSize.width, swipeDistanceInY - contentSize.width, contentSize.width, contentSize.height)];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!_swiping) return;
// You can set the last position when touches end.
// E.g. You can set positions like slide page does, just the the origin of _yourView.
}
If you just want translate in vertical and horizontal direction, you can use UIScrolView instead. :)

You can just add this method to your subclassed UIView class.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint currentLocation = [touch locationInView:self];
CGPoint previousLocation= [touch previousLocationInView:self];
CGFloat deltaX = currentLocation.x - previousLocation.x;
CGFloat deltaY = currentLocation.y - previousLocation.y;
self.frame = CGRectMake(self.frame.origin.x + deltaX, self.frame.origin.y + deltaY, self.frame.size.width, self.frame.size.height);
}

Related

How can I make UITouches offset?

In the image below, I draw and the result is at point A, right where my finger touches.
How can I make the image appear about 40pt above my actual touch. (B)
I'm using the classic coreGraphic UITouch code, like so:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// add the first touch
UITouch *touch = [touches anyObject];
previousPoint1 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
//transform = CGAffineTransformTranslate(self.transform, 5.0, 10.0)
// init the bezier path
self.currentTool = [self toolWithCurrentSettings];
self.currentTool.lineWidth = self.lineWidth;
self.currentTool.lineColor = self.lineColor;
self.currentTool.lineAlpha = self.lineAlpha;
[self.pathArray addObject:self.currentTool];
[self.undoStates addObject:[self.currentTool captureToolState]];
[self.currentTool setInitialPoint:currentPoint];
}
// call the delegate
if ([self.delegate respondsToSelector:#selector(drawingView:willBeginDrawUsingTool:)]) {
[self.delegate drawingView:self willBeginDrawUsingTool:self.currentTool];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// save all the touches in the path
UITouch *touch = [touches anyObject];
previousPoint2 = previousPoint1;
previousPoint1 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
[self.currentTool moveFromPoint:previousPoint1 toPoint:currentPoint];
[self setNeedsDisplay];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// make sure a point is recorded
[self touchesMoved:touches withEvent:event];
CGPoint point = [[touches anyObject] locationInView:self];
[self.currentTool setInitialPoint:point];
self.draggableTextView = ((ACEDrawingDraggableTextTool *)self.currentTool).labelView;
[self.pathArray addObject:self.currentTool];
[self finishDrawing];
[self finishDrawing];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
// make sure a point is recorded
[self touchesEnded:touches withEvent:event];
}
previousPoint1 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
// add these 2 lines below:
previousPoint1 = CGPointMake(previousPoint1.x, previousPoint1.y+40);
currentPoint = CGPointMake(currentPoint.x, currentPoint.y+40);

Rotating a wheel?

I have read here a few examples about that, but couldn't make it work.
I have some UIView called Wheel , in which i want to rotate while touch and drag.
It should work like a real wheel, so if i touch at some point it will NOT rotate to that point, only when i drag my finger, i will get rotation .
I tried this,but i get a full rotation for every little move i do. I would like to ADD the angel to the view, not ROTATE to the new angel ..
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self];
CGPoint center=wheel.center;
float xLeg = fabs(center.x - touchPoint.x);
float yLeg = fabs(center.y-touchPoint.y);
float angle = atan(xLeg / yLeg);
NSLog(#"%f",angle);
wheel.transform = CGAffineTransformMakeRotation( angleInDegree );
}
This should do the trick. Notice how I store the first touch point in touchesBegan:withEvent:. This allows me to subtract the first touch point from every touch point I get while dragging, and thus gives me the real angle I need to rotate.
EDIT
I've done some adjustments, so that it is now smooth and regular even after several touches.
Demo
WheelViewController.m
#interface WheelViewController () {
CGPoint startPoint;
CGFloat startAngle;
CGFloat endAngle;
}
#end
#implementation WheelViewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
startPoint = [touch locationInView:self.view];
startAngle = [self angleForTouchPoint:startPoint] - endAngle;
NSLog(#"\r\nStart angle: %f", startAngle);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
CGFloat touchAngle = [self angleForTouchPoint:touchPoint];
NSLog(#"Touch angle: %f", touchAngle);
self.wheel.transform = CGAffineTransformMakeRotation(fmodf(touchAngle - startAngle, 2 * M_PI));
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
endAngle = [self angleForTouchPoint:touchPoint] - startAngle;
NSLog(#"End angle: %f", endAngle);
}
- (CGFloat)angleForTouchPoint:(CGPoint)touchPoint {
CGPoint center = self.wheel.center;
float xLeg = touchPoint.x - center.x;
float yLeg = touchPoint.y - center.y;
float angle = fmodf(atan(yLeg/xLeg), (2 * M_PI));
if (xLeg < 0) {
angle += M_PI;
}
return angle;
}

Using collision on bounds of UIView

I have an ImageView that moves around the UIView, is it possible to detect collision of the ImageView and the view its self? For example the ImageView hits the side of the view I want it to run an action. -(void)restart {}
If this is possible can you detect which side it has collided with?
You can create a custom UIImageVIew and implement the methods touchBegan and touchMoved (don't forget to add [self setUserInteractionEnabled:YES] in your init method). Then set the rect you want to interact with :
customImageView.interactRect = myView.frame;
And in your customImageView you can add something like:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
lastPosition = [touch locationInView: self.superview];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint position = [touch locationInView:self.superview];
CGRect currentFrame = self.frame;
currentFrame.origin = CGPointMake(currentFrame.origin.x + position.x - lastPosition.x, currentFrame.origin.y + position.y - lastPosition.y);
if (CGRectIntersectsRect(currentFrame, interactRect) && !CGRectIntersectsRect(self.frame, interactRect))
{
NSLog(#"I'm in for the first time");
if(self.frame.origin.x + self.frame.size.width <= interactRect.origin.x && currentFrame.origin.x + currentFrame.size.width > interactRect.origin.x)
{
NSLog(#"Coming from the left");
}
if(self.frame.origin.x >= interactRect.origin.x + interactRect.size.width && currentFrame.origin.x < interactRect.origin.x + interactRect.size.width)
{
NSLog(#"Coming from the right");
}
}
self.frame = currentFrame;
lastPosition = position;
}

objective c - Rotating image using CFAffineMakeRotation

I have been trying to get a UIImageView to rotate around a point when I touch and drag on it. I am having the problem where it jumps back to its original position if I try and rotate it a second time. I have tried the solution here, but that makes the image spin crazily!
What am I doing wrong? Here's my code:
Updated code with fixes:
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
if (CGRectContainsPoint(Game10Wheel.frame, location)) {
Game10Angle = atan2([Game10Wheel center].y - location.y, [Game10Wheel center].x - location.x);
Game10WheelTouched = true;
}
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (Game10WheelTouched) {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
float theAngle = atan2([Game10Wheel center].y - location.y, [Game10Wheel center].x - location.x);
[Game10Wheel setTransform: CGAffineTransformRotate([Game10Wheel transform], theAngle - Game10Angle)];
Game10Angle = theAngle;
}
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
Game10WheelTouched = false;
}
-(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
Game10WheelTouched = false;
}
Thanks!
Your problem in calculation of the angle of rotation for further transformation. Try use code below.
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
float theAngle = atan2([Game10Wheel center].y - location.y, [Game10Wheel center].x - location.x);
[Game10Wheel setTransform: CGAffineTransformRotate([Game10Wheel transform], theAngle - Game10Angle)];
Game10Angle = theAngle;
}
You need to modify the current transformation of the object, otherwise you are just setting it to an initial value. Using CGAffineTransformMakeRotation creates a new transform object with only the rotation specified applied to it. What you want to do is use CGAffineTransformRotate and pass the current transform of the Game10Wheel object to add the rotation to that current transform.
EDIT: In other words, when you create your rotation, it should start from the current transform of the Game10Wheel, not from a new transformation.

How will I hold and drag the image while it is moving?

Here is my code in moving the image randomly and for the touch code.
-(void)viewDidAppear:(BOOL)animated {
timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(randomizeXandY) userInfo:nil repeats:YES];
}
-(void)randomizeXandY {
CGFloat x = (CGFloat) (arc4random() % (int) self.view.bounds.size.width);
CGFloat y = (CGFloat) (arc4random() % (int) self.view.bounds.size.height);
[self moveObjectsAtX:x Y:y];
}
-(void)moveObjectsAtX:(CGFloat)x Y:(CGFloat)y {
[UIView animateWithDuration:5 animations:^{
imgView.center = CGPointMake(x, y);
}];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches]anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if ([touch view] == imgView) {
imgView.center = touchLocation;
}
}
Try the code in touchesBegin and touchesEnded
-(void)touchesBegin:(NSSet *)touches withEvent:(UIEvent *)event {
// stop timers here
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// start timers here again
}
I would rather suggest to use UIPanGestureRecognizer. In it's handling method you can check possible states of the touch.
-(void)handlePan:(UIPanGestureRecognizer *)recognizer {
switch (recognizer.state) {
case UIGestureRecognizerStateBegan: {
CGPoint touchLocation = [recognizer locationInView:self.view];
...
break;
}
case UIGestureRecognizerStateChanged:
...
break;
case UIGestureRecognizerStateEnded:
...
break;
default:
break;
}
You have to use these methods:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
//...
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
//..
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
//...
}
in touchesBegan method, check if the touch is on your image:
if (CGRectContainsPoint(yourImage.frame, touchLocation)){
dragging = YES;
}
if it yes set a global variable, for example bool dragging to YES.
in touchesMoved:
check
if (dragging){
yourImage.frame = CGRectMake(touchLocation.x, touchLocation.y,yourImage.frame.size.widht,yourImage.frame.size.height);
}
in touchesEnded:
set dragging to NO
dragging = NO;
So :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if (CGRectContainsPoint(yourImage.frame, touchLocation)){
dragging = YES;
[timer invalidate];
timer = nil;
}
//...
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if (dragging){
yourImage.frame = CGRectMake(touchLocation.x, touchLocation.y,yourImage.frame.size.widht,yourImage.frame.size.height);
}
//..
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
dragging = NO;
//...
}

Resources