I am performing a task in such a way that I took one image and twenty to thirty rectangular cell button.
For those rectangular cells I named them as 1,2,3,4,5,--------,30. I arranged the rectangular cells in an 6*7 matrix. Now if I click the rectangular cell button 29, the image has to find the shortest path in that matrix to reach that clicked button.
How do I perform this?
You have a single image that you want to animate to the location of one of 30 buttons? Further, you want it to move not in a diagonal, but first horizontally, then vertically? CodaFi's code is quite close to what I would do. I'd write an IBAction method that I would attach to all the buttons. Startig with CodaFi's code as a basis, here's the action method I'd suggest:
-(IBAction)animateImageToButton: (id) sender
{
button = (UIButton *) sender;
//First animate the image to the x position of the button
CGPoint fPoint = CGPointMake(button.center.x, image.center.y);
CGPoint sPoint = button.center;
//animate x position first.
[UIView animateWithDuration: 1.0f animations: ^
{
[image setCenter:fPoint];
}
completion ^(BOOL finished)
{
//Once that animation is complete, create
//a second animation to move to the button's y position
[UIView animateWithDuration: 1.0f animations: ^
{
[image setCenter:sPoint];
}];
}];
}
That code would move a single UIImageView, called Image, onto the button that was tapped.
I would not name the buttons but give them tags. I would use the following scheme:
button.tag = xCoordinate *100 + yCoordinate;
So, for example, for the third button from the left in the top row the tag would be 301. Retrieve the coordinates like this:
xCoordinate = button.tag / 100;
yCoordinate = button.tag % 100;
Now all you have to do is animate the image to the center of the button or some other point near there by changing the x and y coordinates of the image's frame.
I disagree with the tag approach that mundi's layed out, because the images would move in diagonal lines to reach their destination. I imagine a for-loop would be appropriate, so here's my approach:
-(void)animateOnLinesWithClickedButton:(UIButton*)button {
for (UIButton *image in self.view.subviews){
CGPoint fPoint = CGPointMake(button.center.x, image.center.y);
CGPoint sPoint = button.center;
//animate x position first.
[UIView animateWithDuration:1.0f animations:^{
[image setCenter:fPoint];
}
completion^(BOOL finished){
[UIView animateWithDuration:1.0f animations:^{
[image setCenter:sPoint];
}];
}];
}
}
This will animate your buttons one by one to the correct x, then y position. Use the delay variation of this method to create a more realistic effect.
Related
I have a page in my app in which there is user's profile pic in a circle as its there in Twitter profile page.
I have to add a functionality such that when I tap on it, the image should expand. Animation needs to be added in such a way that a new bigger circle should slowly appear from the centre of the smaller circle and reach the centre of the screen.
Any ideas as to how this can be implemented?
Try UIView Animation block with changing bigger circle's position, size, alpha, and corner radius (if required).
Place your bigger circle (with smaller size initially) on top of smaller circle and hide it initially. Then before animation, un-hide it and animate using a block like this:
[UIView animateWithDuration:1.0 animations:^{
// set bigger circle destination position i.e. centre of screen
// set bigger circle final size
// set other properties like alpha, corner radius etc
} completion:nil];
Use CATransform3DScale transform and UIView Animation
CATransform3D avatarTransform = CATransform3DIdentity;
avatarTransform = CATransform3DScale(avatarTransform, avatarScaleFactor,avatarScaleFactor, 0);
[UIView animateWithDuration:1.0 animations:^{
//Change the frame to reach the center of screen
self.avatar.layer.transform = headerTransform
} completion:nil]
You can simply use CGAffineTransformScale and scale your ImageView inside UIView's animateWithDuration block.
imgV.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.0, 0.0);
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
imgV.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
}
completion:^(BOOL finished) {
NSLog(#"done");
}];
For further references you can look into these Stackoverflow questions :
Animate a UIImageView
iOS View Transform Animation
I am trying to make multiple UILabels (using a for loop and inserting them into an array) move horizontally across the screen. I have the labels, I have the array, but I cannot figure out how to use animations to get them to move. I tried using [self.array setValue #0 forKey:#"XPOSITION"]; but I do not know how to write the x position. Is there no real way to change the x position in an array? Will I have to make each one its own individual thing and use object.frame = CGRectMake(newx,y,w,h); which seems a bit tedious? Thank you in advance!
Following Aderis' advice about setting the center, you have to use a for loop to set the center of each label.
for (UILabel *label in self.array) {
CGPoint oldCenter = label.center;
label.center = CGPoint(oldCenter.x + 20, oldCenter.y);
}
Where you would change 20 to be whatever value you actually wanted to change the x coordinate by.
If you want to have it animated, you can use this:
[UIView animateWithDuration:0.2 animations:^{
for (UILabel *label in self.array) {
CGPoint oldCenter = label.center;
label.center = CGPoint(oldCenter.x + 20, oldCenter.y);
}
}];
Where you would replace 0.2 with the length in seconds you want the animation to last.
You should try using the builtin animation capabilities of UIView. You can do the following code:
[UIView beginAnimations:nil context:nil];
for (UIView* view in myArray)
{
[view setCenter:thisViewsTargetCenterPoint];
}
[UIView commitAnimations];
In the for loop, you should do all the UI positioning changes you want, and once you call commitAnimations, UIKit will do all the position changes through animations.
I have a 3x3 grid of UIViews with UIGestureRecognizers added to them, arranged like so:
The way it works is that tapping on a square enlarges it 2x using CGAffineTransformScale and overlays that over the other squares. The problem is that the touch area stays the same size as the 1.0 scale for some reason.
I add the squares using
CGRect squareFrame = CGRectMake(1 + squareSpacing + ((squareDimension + squareSpacing) * i), topMargin, squareDimension, squareDimension);
SquareView *square = [[SquareView alloc] initWithFrame:squareFrame];
[square setPosition:i];
square.layer.zPosition = 0;
[self.view addSubview:square];
[squaresArray addObject:square];
The Squares have gesture recognizers added in their init:
fingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[self addGestureRecognizer:fingerTap];
The tapped function does the following:
[UIView animateWithDuration:1.0
delay:0.0
usingSpringWithDamping:0.8
initialSpringVelocity:10.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
CGAffineTransform transform = self.transform;
self.transform = CGAffineTransformScale(transform, 2.0, 2.0);
}
completion:nil];
I outlined the touch area in red. I have tried playing with the zPosition but I don't know what to do to make it work, I am stuck. I want to be able to tap the enlarged square anywhere for it to close, but I am limited to the red area.
Thanks in advance.
EDIT: Sorry that the pictures are so large. Code added.
Steven
You might trying bringing the expanded UIView to the front of your parent view so that your tap events aren't captured by any overlapped views:
[parentView bringSubviewToFront:tappedView];
i have simple UIView animation block which animates the origin of 2 views. I have a Button on a special position placed on a mapview view. so when i'd like to animate the center of the map and move the pin with the map, the map moves faster than the button. Is there a way, to speed up the animation of the button or to slow down the animation of the map? At the moment it looks like the map moves and the button jumps to his end position.
CGPoint newCenter = mapView.center;
newCenter.x -= 1;
newCenter.y -= (button.frame.size.height/2)
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationCurveEaseIn animations:^{
CGPoint screenPoint = fakePin.frame.origin;
screenPoint.x -= 5;
screenPoint.y += button.frame.size.height-4;
mapView.mapCoord = [mapView.map convertPoint:screenPoint toCoordinateFromView:self.view];
self.mapView.map.centerCoordinate = mapView.mapCoord;
[button setCenter:newCenter];
}];
Any Ideas?
Why not show the button as an annotation? Then it would move along the map.
Still, try to animate the property frame on the button instead of center. You'll need to do the calculations on your own but I think that may be the problem.
i just figured out, that the Problem was that my setCenter: was called without animating, somehow it worked with the Google Maps in ios5 (animating itself but not in ios6=
No it works!!
I have a problem with a UIView-subclass object that I am rotating using Core Animation in response to a UISwipeGesture.
To describe the context: I have a round dial that I have drawn in CG and added to the main view as a subview.
In response to swipe gestures I am instructing it to rotate 15 degrees in either direction dependent on whether it;s a left or right swipe.
The problem that it will only rotate each way once. Subsequent gestures are recognised (evident from other actions that are triggered) but the animation does not repeat. I can go left once then right once. But trying to go in either direction multiple times doesn't work. Here's the relevant code, let me know your thoughts...
- (IBAction)handleLeftSwipe:(UISwipeGestureRecognizer *)sender
{
if ([control1 pointInside:[sender locationInView:control1] withEvent:nil])
{
//updates the display value
testDisplay.displayValue = testDisplay.displayValue + 0.1;
[testDisplay setNeedsDisplay];
//rotates the dial
[UIView animateWithDuration:0.25 animations:^{
CGAffineTransform xform = CGAffineTransformMakeRotation(radians(+15));
control1.transform = xform;
[control1 setNeedsDisplay];
}];
}
CGAffineTransform xform = CGAffineTransformMakeRotation(radians(+15));
Do you keep a total of how far the rotation is. CGAffineTransformMakeRotation are not additive. Only the most recent is used. So you are setting it to 15 each time, not 15 more each time.
Here's a super simple example of rotating a view cumulatively. This rotates the view by 180 degrees each button press.
- (IBAction) onRotateMyView: (id) sender
{
[UIView animateWithDuration:0.3 animations:^{
myView.transform = CGAffineTransformMakeRotation(M_PI/2*rotationCounter);
} completion:^(BOOL finished){
//No nothing
}];
++rotationCounter;
}