how move an image on mainview - iphone

i've got a problem with iPhone SDK.
I want create an imageView that user can touch and move and scale as he wish.
How can i do this?
Thank you

the easy way is to put it in a UIScrollView and enable the methods of the UIScrollViewDelegate that you wan't to use (scrool / zoom)
take a look at the apple sample project "PhotoScroller", you can find it in xCode help...
ciao,
luca

Look at UIGestureRecognizer : http://developer.apple.com/library/ios/#documentation/uikit/reference/UIGestureRecognizer_Class/Reference/Reference.html
Especially, UIPanGestureRecognizer and UIPinchGestureRecognizer

for moving an object, you can CGAfflineTransformation to move from x axis to y axis.
u write up those code in Touch Delegates. also set the UIImage frame as CGRectZero.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.50];
titl.transform=CGAffineTransformMakeTranslation(260, 0);
comment.transform=CGAffineTransformMakeTranslation(0, 100);
[UIView commitAnimations];
this is the code to move an object from one place to another. this might help you

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[UIView beginAnimations:nil context:NULL];
CGPoint touchPoint = [[touches anyObject] locationInView:[self window]];
float deltaX = touchPoint.x - lastUpdatedPoint.x;
float deltaY = touchPoint.y - lastUpdatedPoint.y;
float newCenterX = [[self layer] position].x + deltaX; float newCenterY = [[self layer] position].y + deltaY;
CGPoint center = CGPointMake(newCenterX, newCenterY);
[[self layer] setPosition:center];
lastUpdatedPoint = touchPoint;
[UIView commitAnimations];
}
BY
CNSivakumar

Related

How To Rotate an UIImageView based on a point in Touches Moved Method?

Dear All,
I want to rotate a UIImageView relative to a point in touchesMoved method.
I tried 2 -3 methods but I am not getting the exact result what I expected to be.
First method I used
CGAffineTransform transforms = CGAffineTransformMakeRotation(M_PI/2);
imgView.transform = transforms;
This is written in touchesMoved. So I expect a rotation for the image view in each touchesMoved.
But the rotation is occuring only once .
Second method I used was
CGAffineTransform transforms = CGAffineTransformRotate(imgView.transform, M_PI/2);
imgView.transform = transforms;
Now the result what I get is the image in Image view is continusely rotating in each move. But imageview is not rotating. What i need is to rotate the imageview not the image.
Any help will be greatly appreciated.
Thanks & Best Regards,
Rupesh R Menon
If I understood correctly you want to achieve single finger rotation on the image. If it is so you can use following functions from one of my live working project. You can use this for single image as well as multiple images. You need to modify at some extend for multiple images. Best way is extend UIImageView class and create your own class.
From touches moved call this function
[self transformImagewithTouches:touch];
Declare 1 property and synthesize as follows. (Also please declare other variables if required in below code.
#property (nonatomic) CGFloat fltRotatedAngle;
-(void)transformImagewithTouches:(UITouch *)touchLocation
{
//NSLog(#"Before %f",self.fltRotatedAngle);
CGPoint touchLocationpoint = [touchLocation locationInView:[self superview]];
CGPoint PrevioustouchLocationpoint = [touchLocation previousLocationInView:[self superview]];
CGPoint origin;
origin.x=self.center.x;
origin.y=self.center.y;
CGPoint previousDifference = [self vectorFromPoint:origin toPoint:PrevioustouchLocationpoint];
CGAffineTransform newTransform =CGAffineTransformScale(self.transform, 1, 1);
CGFloat previousRotation = atan2(previousDifference.y, previousDifference.x);
CGPoint currentDifference = [self vectorFromPoint:origin toPoint:touchLocationpoint];
CGFloat currentRotation = atan2(currentDifference.y, currentDifference.x);
CGFloat newAngle = currentRotation- previousRotation;
//Calculate Angle to Store
fltTmpAngle = fltTmpAngle+newAngle;
self.fltRotatedAngle = (fltTmpAngle*180)/M_PI;
newTransform = CGAffineTransformRotate(newTransform, newAngle);
[self animateImageView:self toPosition:newTransform];
}
-(void)animateImageView:(UIImageView *)theView toPosition:(CGAffineTransform) newTransform
{
[UIView setAnimationsEnabled:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.0750];
self.transform = newTransform;
[UIView commitAnimations];
}
-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint
{
CGFloat x = secondPoint.x - firstPoint.x;
CGFloat y = secondPoint.y - firstPoint.y;
CGPoint result = CGPointMake(x, y);
return result;
}
Hope it helps. If you stuck up please let me know I ll definitely help you.
Thanks for the interest shown by you in helping me.
When I used the following code I was able to rotate the image view in my desired angle.
imgView.layer.transform = CATransform3DMakeRotation(pCalculator.tangentToCornerAngle, 0, 0, 1);
where imgView is an UIImageView.
pCalculator.tangentToCornerAngle is the desired angle in which rotation has to be made.
Function is CATransform3DMakeRotation(CGFloat angle, CGFloat x, <CGFloat y, CGFloat z);
Thankyou All,
Rupesh R Menon
It's because you have rotated it by M_PI/2 and when you rotate it again it rotates it from the initial position. Use this one
CGAffineTransform transforms = CGAffineTransformConcat(imgView.transform,CGAffineTransformMakeRotation(M_PI/2));
imgView.transform = transforms;

UIView Rotation

Hello All I want to rotate UIView on single finger touch and it still rotate untill finger moves on screen of iPhone and it stops rotation when I stop the finger moving or remove it from screen.
Thanks in Advance.
Try similar code
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2];
CGAffineTransform rr=CGAffineTransformMakeRotation(5);
yourView.transform=CGAffineTransformConcat(yourView.transform, rr);
[UIView commitAnimations];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesBegan:touches withEvent:event];
}
Pradeepa's code is nice, however, that animation system is getting deprecated (if not already). Try something like this instead:
CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
double startRotationValue = [[[yourView.layer presentationLayer] valueForKeyPath:#"transform.rotation.z"] doubleValue];
rotation.fromValue = [NSNumber numberWithDouble:startRotationValue];
rotation.toValue = [NSNumber numberWithDouble:startRotationValue+5];
rotation.duration = 0.2;
[yourView.layer addAnimation:rotation forKey:#"rotating"];
I took Pradeepa's numbers to make them comparable, but i believe Apple prefers you using this or block-based animation instead of the old system.
rotating a view on touch may help you

Slide textview horizontal without using paging

I`m using a simple Textview in an tabbased application to display some text :) I figerd out how to change the text animated using the following code:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self];
// To be a swipe, direction of touch must be horizontal and long enough.
if (fabsf(startTouchPosition.x - currentTouchPosition.x) >= HORIZ_SWIPE_DRAG_MIN &&
fabsf(startTouchPosition.y - currentTouchPosition.y) <= VERT_SWIPE_DRAG_MAX)
{
// It appears to be a swipe.
if (startTouchPosition.x < currentTouchPosition.x){
NSString *string = [[NSString alloc]initWithFormat:#"..."];
self.text = string;
}
else{
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
//[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self superview] cache:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:[self superview] cache:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5];
[[self superview] exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
[UIView commitAnimations];
[self displayNewText];
}
}
However there is now "slide transition" defined in UIViewAnimationTransition. I know about paging, but I don`t want to use this. Is there an other possibility to have an horizontal slide animation when detecting a horizontal swipe?
I think you are almost there. Intercept touchesMoved:withEvent method just like in your current code and update the visible area of the UIScrollView object.
I hope you don't have to detect touches for your requirement use UIScrollView as parent view for UITextView.
scroll=[[UIScrollView alloc]initWithFrame:CGRectMake(0,40, 320,200)];
[scroll setContentSize:CGSizeMake(640, 200)];
Or if you want to animate the view you can use affine transforms.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
someview.transform=CGAffineTransformMakeTranslation(-100, 0);
[UIView commitAnimations];

View rotation in touchesMoved

I rotate a view by 45 degree on every dragging. Here is my code. Problem here is that the view is rotated only once. After that there is no rotation. What will be the reason? Any help
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0];
dialView.transform = CGAffineTransformMakeRotation(45* M_PI/180);
[UIView commitAnimations];
}
You can also use CGAffineTransformRotate to rotate from its present transform, as in:
dialView.transform = CGAffineTransformRotate(dialView.transform, 45 * M_PI / 180);
The rotation is always relative to 0. If you rotate to x several times it will rotate only the first time.
If you want to rotate 45 everytime you call that code, you will need to have counter and it would look like this:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
step++;//You are supposed to keep this variable global.
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0];
dialView.transform = CGAffineTransformMakeRotation(45*step* M_PI/180);
[UIView commitAnimations];
}

How should I interact with the geometry of a UIView, disregarding any transforms applied?

I have a view that I would like the user to rotate around its center, by tapping and holding somewhere and just move their finger round and round.
I have all the geometry worked out; What I do is store the initial touch angle relative to the center as offsetAngle, then my touchesMoved method looks like this:
- (void) touchesMoved: (NSSet *)touches withEvent:(UIEvent *)event {
self.transform = CGAffineTransformMakeRotation(0);
CGPoint location = [[touches anyObject] locationInView: self];
CGPoint actualCenter = [self convertPoint: self.center fromView: self.superview];
CGPoint relativeTouch = [MathHelper translatePoint:location relativeTo: actualCenter];
CGPoint zero = CGPointMake(0, 0);
float angle = [MathHelper getAngleForPoint:zero andPoint:relativeTouch];
self.transform = CGAffineTransformMakeRotation(offsetAngle-angle);
}
The ugly bit is the first line, where I have to restore the rotation in order to get the correct event positions in the view. If I don't that, then the locations jump all over the place as there's no continuity, since the view is rotating...
Another issue is when you want to manipulate a view's frame (eg. moving it down), when the view has a transform applied:
- (IBAction)toggleSettingsView {
BOOL state = [settingsSwitch isOn];
float height = optionsView.bounds.size.height;
CGRect polygonFrame = polygonView.frame;
[UIView beginAnimations:#"advancedAnimations" context:nil];
[UIView setAnimationDuration:0.3];
if (state) {
optionsView.alpha = 1.0;
polygonFrame.origin.y += height;
} else {
optionsView.alpha = 0.0;
polygonFrame.origin.y -= height;
}
polygonView.frame = polygonFrame;
[UIView commitAnimations];
}
This distorts the view heavily.
I must mention that both the CGTransform and the CALayer transform have the same effect.
This smells like I'm doing something wrong, but I don't know what I should be doing.
I would use the coordinate system of the superview, since it is unaffected by the rotation:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint location = [[touches anyObject] locationInView:self.superview];
CGPoint relativeTouch = [MathHelper translatePoint:location relativeTo:self.center];
CGPoint zero = CGPointMake(0, 0);
float angle = [MathHelper getAngleForPoint:zero andPoint:relativeTouch];
self.transform = CGAffineTransformMakeRotation(offsetAngle-angle);
}
Just save the original transform in an ivar and call it a day.