how to detect wether the UIImage is moving - iphone

I am creating an UIImageView through timer which is called in touchesended and moving it. After completion of animation I am removing its object. If I touch the screen continuously 6 to 7 times, one of the image(created from the timer code block) is not moving and so not deallocating..
this is my code:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
flakeImage = [UIImage imageNamed:#"bubble.png"];
TimerView1=[NSTimer scheduledTimerWithTimeInterval:(0.1) target:self selector:#selector(onTimer:) userInfo:[NSValue valueWithCGPoint:location] repeats:NO];
}
- (void)onTimer:(id) sender {
NSValue *value=[TimerView1 userInfo];
CGPoint location = [value CGPointValue];
int time= [secLabel.text intValue];
int tick = 0;
tick = time+1;
secLabel.text = [NSString stringWithFormat:#"%.2i", tick];
double scale = 1 / round(random() % 100) + 1.0;
double speed = 1 / round(random() % 100) + 1.0;
UIImageView* flakeView1 = [[UIImageView alloc]initWithImage:flakeImage];
flakeView1.tag=100;
int endX = round(random() % 320);
int endY = round(random() % 480);
flakeView1.frame = CGRectMake(location.x, location.y, 35.0 * scale, 35.0 * scale);
[self.view addSubview:flakeView1];
[UIView beginAnimations:nil context:flakeView1];
[UIView setAnimationDuration:6 * speed];
flakeView1.frame = CGRectMake(endX,endY, 5.0 * scale, 5.0 * scale);
[UIView setAnimationDidStopSelector:#selector(onAnimationComplete:finished:context:)];
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
if(tick == 1)
{
[TimerView1 invalidate];
secLabel.text=[NSString stringWithFormat:#"0"];
}
}
- (void)onAnimationComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
UIImageView *flakeView1 = context;
[flakeView1 removeFromSuperview];
[flakeView1 release];
flakeView1=nil;
}
I dont know why it is happening..Is there any way to detect if that image is moving or not?
I have seen many posts, they suggest to use animationKeys.How to use that for detecting if image is Animating or not?

Related

how do I stack the UIImage together and wavering or swing in UIKit

I would like to know how this app stacks up uiimage and wavering in UIKit.
I'm following this xcode: Using a UIImageView subclass with NSTimers
to have images dropping down in random, but how do I catch it and stack the UIImage together ?
Thanks for the reply... EDIT: for clarity
https://www.youtube.com/watch?v=2dpZCoi4xFk 40sec onwards will show how it stack on top each other and swing with accerometer
This will emulate the dropping of UIIimageView
- (void)viewDidLoad {
[super viewDidLoad];
// set the background color to something COLD
self.view.backgroundColor = [UIColor colorWithRed:0.0 green:0.5 blue:1.0 alpha:1.0];
// load our ph image we will use the same image over and over
phImage = [UIImage imageNamed:#"placeholder.png"];
// start a timet that will fire 1 times per second
[NSTimer scheduledTimerWithTimeInterval:(1) target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
}
// Timer event is called whenever the timer fires
- (void)onTimer
{
// build a view from our ph image
UIImageView* placeholderView = [[UIImageView alloc] initWithImage:phImage];
// use the random() function to randomize up our ph attributes
//int startX = round(random() % 300);
int startX = round(random() % 275);
//int endX = round(random() % 300);
int endX = startX;
double scale = 1 / round(random() % 100) + 1.0;
double speed = 1 / round(random() % 50) + 1.0;
// set the PH start position
phView.frame = CGRectMake(startX, -100.0, 25.0 * scale, 25.0 * scale);
phView.alpha = 0.25;
// put the ph in our main view
[self.view addSubview:phView];
[UIView beginAnimations:nil context:phView];
// set up how fast the ph will fall
[UIView setAnimationDuration:5 * speed];
// set the postion where ph will move to
phView.frame = CGRectMake(endX, 500.0, 25.0 * scale, 25.0 * scale);
// set a stop callback so we can cleanup the ph when it reaches the
// end of its animation
[UIView setAnimationDidStopSelector:#selector(onAnimationComplete:finished:context:)];
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
}
- (void)onAnimationComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
UIImageView *phView = context;
[phView removeFromSuperview];
NSLog(#"[phView retainCount] = %d",[phView retainCount]);
}
Thanks for reading and commenting.
For stacking, just make a UIView that holds all the placed images together.
UIView *stackView = [UIView new];
-(void) addView: (UIView*) view toStack: (UIView*) stackView
{
if ([stackView subviews].count > 0)
{
CGRect frame = [[[stackView subviews] lastObject] frame];
view.frame = CGRectOffset(frame, 0, 20);
}
[stackView addSubview:view];
}
For tilting, set up an accelerometer and use the x and y to determine the tilt.
-(void)configureAccelerometer
{
UIAccelerometer* theAccelerometer = [UIAccelerometer sharedAccelerometer];
theAccelerometer.updateInterval = 0.20;
theAccelerometer.delegate = self;
// Delegate events begin immediately.
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
UIAccelerationValue x, y, z;
x = acceleration.x;
y = acceleration.y;
//[stackView tiltForX: x Y: y]
}
More info on Motion Events
For the collision detection, you can probably do something like
if (CGRectIntersectsRect([[[stackView subviews] lastObject] frame], fallingView.frame))
[self addView: fallingView toStack: stackView];

iphone - how to scroll uiscrollview from event touched by uibutton in scrollview

structure
UIViewController
- UIScrollview
- UIButton
I'm going to make scrollview can receive button event. So whenever user do scrolling(dragging) on the button, the scrollview react as scrolling itself.
I made button down and moved handler with event forwarding like below
- (IBAction)buttonTouchedMove:(id)sender withEvent:(UIEvent *)event {
[[sender nextResponder] touchesMoved:[event allTouches] withEvent:event];
}
- (IBAction)buttonTouchedDown:(id)sender withEvent:(UIEvent *)event {
[[sender nextResponder] touchesBegan:[event allTouches] withEvent:event];
}
and to move scrollview as touches change, I made below codes
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
self.oldPoint = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint offset = self.scrollView1.contentOffset;
UITouch *touch = [touches anyObject];
self.newPoint = [touch locationInView:self.view];
int diffX = newPoint.x - oldPoint.x;
offset.x = offset.x - diffX;
[scrollView1 setContentOffset:offset animated:YES];
self.oldPoint = self.newPoint;
}
but, scrollview react strange.. not move enough as I touch moved.
// get the button width
CGFloat buttonWidth = self.theButton.frame.size.width;
// replace your button name here
// now get the view width
CGFloat viewWidth = self.view.frame.size.width;
// replace your view name here
// now get the multiplier which i said u as 10
CGFloat mult = viewWidth / buttonWidth;
// and now use it in your code
.
.
.
diffX = mult*(newPoint.x - oldPoint.x);
.
.
.
Final answer, Using UIView animation, I got what i want.
- (IBAction)buttonTouchedDown:(id)sender withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
self.oldPoint = [touch locationInView:self.view];
self.velocity = 0;
isButtonTouchedDown = YES;
}
- (IBAction)buttonTouchedMove:(id)sender withEvent:(UIEvent *)event {
CGPoint offset = self.scrollView1.contentOffset;
UITouch *touch = [[event allTouches] anyObject];
self.newPoint = [touch locationInView:self.view];
int diffX = self.newPoint.x - self.oldPoint.x;
velocity = diffX;
offset.x = offset.x - diffX;
[self.scrollView1 setContentOffset:offset animated:NO];
self.oldPoint = self.newPoint;
}
There is a trick..I calculated velocity by differentiating moved distance in TouchedMove function.
In Button TouchUp event handler, I controlled Scrollview with velocity value and CurveEaseout animation to scroll more. By offering very short duration of animation and repeating it if there is no event(button touched down). It becomes very similar with scrollview's animation.
- (IBAction)buttonTouchedUp:(id)sender withEvent:(UIEvent *)event {
CGPoint offset = self.scrollView1.contentOffset;
amountX = (self.velocity)*(abs(self.velocity));
dX = amountX;
isButtonTouchedDown = NO;
if (offset.x - amountX < 0) {
offset.x = 0;
[scrollView1 setContentOffset:offset animated:YES];
}
else if (abs(dX) < 70) { // 70: content item size
offset.x = roundf(offset.x/70)*70;
[scrollView1 setContentOffset:offset animated:YES];
}
else {
[self endScrollAnimation];
}
- (void)startAnimation:(float)x moveAmount:(float)moveAmount
{
CGPoint offset = self.scrollView1.contentOffset;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
offset.x = x < 0 ? offset.x + moveAmount : offset.x -moveAmount;
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(endScrollAnimation)];
[scrollView1 setContentOffset:offset animated:NO];
[UIView commitAnimations];
}
- (void)endScrollAnimation
{
CGPoint offset = self.scrollView1.contentOffset;
float slowMoveAmount = abs(amountX) * 0.05;
float fastMoveAmount = abs(amountX) * 0.1;
if (isButtonTouchedDown) {
return;
}
else if (abs(dX) > abs(amountX)*0.35 && offset.x > 0) {
[self startAnimation:dX moveAmount:fastMoveAmount];
dX = dX < 0 ? dX + fastMoveAmount : dX -fastMoveAmount;
}
else if (abs(dX) > slowMoveAmount && offset.x > 0) {
[self startAnimation:dX moveAmount:slowMoveAmount];
dX = dX < 0 ? dX + slowMoveAmount : dX - slowMoveAmount;
}
else {
offset.x = roundf(offset.x/70)*70;
[scrollView1 setContentOffset:offset animated:YES];
}
}

TouchEvent doubts in iphone

HA ii ,i have two tableview in one view tableview and tab,the tab is hidden below the mainview,the user can see only tableview in the mainview,for viewing the tab the user have to click button just above the tab,when the user tap the button it drage upwards to the mainview i have done this by using this code
-(IBAction) controlPanelShowHide:(id)sender
{
CGRect frame = tab.frame;
CGRect viewframe = hideviewoftab.frame;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.9];
if (!self.isExpanded)
{
self.isExpanded = YES;
if (frame.origin.y -=240) {
tab.frame = frame;
}
if (imageframe.origin.y -=240) {
btnShowHide.frame =imageframe;
}
if (viewframe.origin.y -=240) {
hideviewoftab.frame =viewframe;
}
} else {
self.isExpanded = NO;
if (frame.origin.y +=240) {
tab.frame = frame;
}
if (imageframe.origin.y +=240) {
btnShowHide.frame =imageframe;
}
if (viewframe.origin.y +=240) {
hideviewoftab.frame =viewframe;
}
}
[UIView commitAnimations];
}
every things work fine with this code,but i need to drag this tab with touch event ,i.e. when the user tap and hold it and drag any-ware on the screen (upwards only)> i think this is done through - (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)eventBut how can we done this ?sorry for the very very poor english.Hope you understand my question.
thanks in advance.
EDIT:
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{ CGPoint pt = [[touches anyObject] locationInView:self];
[tab beginAnimations:nil context:nil];
[tab setAnimationDuration:0.1];
CGRect newFrame = tab.frame;
newFrame.origin.y += pt.y - touchingPoint.y;
newFrame.origin.x += pt.x - touchingPoint.x;
[self setFrame:newFrame];
[tab commitAnimations];
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
CGPoint pt = [[touches anyObject] locationInView:self];
[tab beginAnimations:nil context:nil];
[tab setAnimationDuration:0.1];
CGRect newFrame = tab.frame;
newFrame.origin.y += pt.y - touchingPoint.y;
[self setFrame:newFrame];
[tab commitAnimations];
}
read this link
How can we move a view vertically upward and downwards?
Here modify the - (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event method with this code
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
CGPoint pt = [[touches anyObject] locationInView:self];
[UITableView beginAnimations:nil context:nil];
[UITableView setAnimationDuration:0.1];
CGRect newFrame = self.frame;
newFrame.origin.y += pt.y - touchingPoint.y;
newFrame.origin.x += pt.x - touchingPoint.x;
[self setFrame:newFrame];
[UITableView commitAnimations];
}

How to rotate UIButton or UIImage view that follows finger (Touch and hold)?

I need some help.How to rotate UIButton or UIImageView that follows finger (Touch and hold, UILongPressGestureRecognizer)? Thx 4 help
UPD: Don't understand what i'm doing wrong?
- (void)viewDidLoad {
UITapGestureRecognizer *tapgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)];
[self.view addGestureRecognizer:tapgr];
[tapgr release];
[super viewDidLoad];
}
-(void)tap:(UITapGestureRecognizer *)gesture {
CGPoint touch = [gesture locationInView:self.view];
CGPoint center = myImage.center;
float dx,dy,wtf;
dx = touch.x-center.x;
dy = touch.y-center.y;
wtf = atan2f(dy, dx);
[self rotateImage:self.myImage withAngle:wtf];
}
- (void)rotateImage:(UIImageView *)image withAngle:(float)newAngle
{
image.transform = CGAffineTransformMakeRotation(newAngle);
}
Glad I remember triginometry
-(void)degreesToRotateObjectWithPosition:(CGPoint)objPos andTouchPoint:(CGPoint)touchPoint{
float dX = touchPoint.x-objPos.x; // distance along X
float dY = touchPoint.y-objPos.y; // distance along Y
float radians = atan2(dY, dX); // tan = opp / adj
//Now we have to convert radians to degrees:
float degrees = radians*M_PI/360;
return degrees;
}
Once you have your nice method, just do this in the touch event method. (I forgot what it's called...)
CGAffineTransform current = view.transform;
[view setTransform:CGAffineTransformRotate(current, [self degreesTorotateObjectWithPosition:view.frame.origin andTouchPoint:[touch locationInView:parentView]]
//Note: parentView = The view that your object to rotate is sitting in.
This is pretty much all the code that you'll need.The math is right, but I'm not sure about the setTransform stuff. I'm at school writing this in a browser. You should be able to figure it out from here.
Good luck,
Aurum Aquila
- (void) LongPress:(UILongPressGestureRecognizer *)gesture {
CGPoint p = [gesture locationInView:self.view];
CGPoint zero;
zero.x = self.view.bounds.size.width / 2.0;
zero.y = self.view.bounds.size.height / 2.0;
CGPoint newPoint;
newPoint.x = p.x - zero.x;
newPoint.y = zero.y - p.y;
angle = atan2(newPoint.x, newPoint.y);
UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionAllowUserInteraction;
[UIView animateWithDuration:0.2 delay:0.0 options:options
animations:^{myButton.transform = CGAffineTransformRotate(CGAffineTransformIdentity, angle);}
completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 delay:0.5 options:options animations:^{
myButton.transform = CGAffineTransformRotate(CGAffineTransformIdentity, [self detectQuarter:angle]);
} completion:nil];
}];
}
#define M_PI_3_4 3*M_PI_4
-(CGFloat)detectQuarter:(CGFloat)anAngle {
if ((anAngle >= -M_PI_4)&&(anAngle <= M_PI_4)) return 0;
if ((anAngle > M_PI_4) && (anAngle <= 3*M_PI_4)) return M_PI_2;
if ((anAngle >= -M_PI_3_4) && (anAngle < -M_PI_4)) return -M_PI_2;
else return M_PI;
}

Rotate the image corresponding to the touch drag in iPhone

I want to rotate the image in clockwise or anticlockwise direction corresponding to the user touch drag with its speed. I think this can be done with some math and logic. What would a code sample for this look like?
If you're targeting iOS 3.2 or greater, you can use UIRotationGestureRecognizer. The code would look something like this:
In your setup method (viewDidLoad or init, etc,):
UIRotationGestureRecognizer *rotationGesture =
[[UIRotationGestureRecognizer alloc] initWithTarget:self
action:#selector(handleRotate:)];
rotationGesture.delegate = self;
[myImageView addGestureRecognizer:rotationGesture];
[rotationGesture release];
The event handler:
- (void)handleRotate:(UIRotationGestureRecognizer *)recognizer {
if(recognizer.state == UIGestureRecognizerStateBegan ||
recognizer.state == UIGestureRecognizerStateChanged)
{
recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform,
recognizer.rotation);
[recognizer setRotation:0];
}
}
I have some more examples of gesture recognizers (including the one above) on github.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches)
{
currentTouch=touch;
if (CGRectContainsPoint([self.view frame], [touch locationInView:self.ViewRotationArrow]))
{
[self transformSpinnerwithTouches:touch];
}
else if (!CGRectContainsPoint([ViewRotationArrow frame], [touch locationInView:self.ViewRotationArrow])) {
[self dispatchTouchEvent:[touch view]WithTouch:touch];
}
}
}
-(void)transformSpinnerwithTouches:(UITouch *)touchLocation
{
CGPoint touchLocationpoint = [touchLocation locationInView:self.view];
CGPoint PrevioustouchLocationpoint = [touchLocation previousLocationInView:self.view];
//Origin is the respective point. From that I am going to measure the
//angle of the current position with respect to the previous position ....
CGPoint origin;
origin.x=240;
origin.y=160;
//NSLog(#"currentTouch Touch In Location In View:%F %F\n",touchLocationpoint.x,touchLocationpoint.y);
//NSLog(#"currentTouch Touch previous Location In View:%F %F\n",PrevioustouchLocationpoint.x,PrevioustouchLocationpoint.y);
CGPoint previousDifference = [self vectorFromPoint:origin toPoint:PrevioustouchLocationpoint];
CGAffineTransform newTransform =CGAffineTransformScale(ViewRotationArrow.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;
NSLog(#"currentRotation of x %F previousRotation %F\n",currentRotation,previousRotation);
NSLog(#"Angle:%F\n",(temp1*180)/M_PI);
temp1=temp1+newAngle;
//NSLog(#"Angle:%F\n",(temp1*180)/M_PI);
newTransform = CGAffineTransformRotate(newTransform, newAngle);
[self animateView:ViewRotationArrow toPosition:newTransform];
}
-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint
{
CGPoint result;
CGFloat x = secondPoint.x-firstPoint.x;
CGFloat y = secondPoint.y-firstPoint.y;
result = CGPointMake(x, y);
return result;
}
-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform
{
//animating the rotator arrow...
[UIView setAnimationsEnabled:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.0750];
ViewRotationArrow.transform = newTransform;
[UIView commitAnimations];
}
-(void)rotateView
{
//shape of eclipse
CAShapeLayer* circle = [[CAShapeLayer alloc] init];
CGMutablePathRef path = CGPathCreateMutable();
CGRect ViewRect = CGRectMake(self.view.bounds.size.width/2.8, (self.view.bounds.size.height-self.view.bounds.size.width/2)/2, self.view.bounds.size.width/4, self.view.bounds.size.width/2);
float midX = CGRectGetMidX(ViewRect);
float midY = CGRectGetMidY(ViewRect);
CGAffineTransform t = CGAffineTransformConcat(
CGAffineTransformConcat(
CGAffineTransformMakeTranslation(-midX, -midY),
CGAffineTransformMakeRotation(-1.57079633/0.99)),
CGAffineTransformMakeTranslation(midX, midY));
CGPathAddEllipseInRect(path, &t, ViewRect);
circle.path = path;
circle.frame = self.view.bounds;
circle.fillColor = [UIColor clearColor].CGColor;
circle.strokeColor = [UIColor greenColor].CGColor;
circle.lineWidth = 3.0f;
[self.view.layer addSublayer:circle];
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
animation.duration = 0.0f;
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[circle addAnimation:animation forKey:#"strokeEnd"];
// rotateView red color
testView=[[UIView alloc]init];
testView.frame=CGRectMake(0, 0, 20, 20);
testView.backgroundColor=[UIColor redColor];
testView.userInteractionEnabled=YES;
testView.center=CGPathGetCurrentPoint(path);
testView.transform = CGAffineTransformMakeRotation(1.57079633);
[testView sizeToFit];
[self.view.layer addSublayer:testView.layer];
// view Animation
CAKeyframeAnimation* ViewAnimation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
ViewAnimation.duration = 15.0f;
ViewAnimation.path = path;
ViewAnimation.rotationMode = kCAAnimationRotateAuto;
ViewAnimation.calculationMode = kCAAnimationCubicPaced;
//ViewAnimation.removedOnCompletion = NO;
[testView.layer addAnimation:ViewAnimation forKey:#"position"];
}