iOS make object come back up after moving down - ios

I have an object that falls from the top of the screen however i want it to come back up after the bottom of the object reaches the bottom of the screen. This is my code at the moment. I tried adding another image view to trigger the up motion by collision. The timer is in ViewDidLoad
hammer.center = CGPointMake(hammer.center.x, hammer.center.y + 12);
if (CGRectIntersectsRect(hammer.frame, floor.frame)) {
hammer.center = CGPointMake(hammer.center.x , hammer.center.y -50);
}

you wont see it animate, maybe try animating the view instead of moving it instantly.
Place this in viewDidAppear to see it after the view has come on the screen.
[UIView animateWithDuration:0.3f
animations:^{
hammer.center = CGPointMake(hammer.center.x, hammer.center.y + 12);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3f
animations:^{
if (CGRectIntersectsRect(hammer.frame, floor.frame)) {
hammer.center = CGPointMake(hammer.center.x , hammer.center.y -50);
}
}];
}];

Related

iOS Graphic Appear and Fade Out with Alpha

I've been reading about UIView animateWithDuration which I'm trying to use so when a button is pressed a graphic appears then slowly fades out (i.e. alpha is set to 0).
I'm using the code below in my viewdidload just for test purposes however its not working:
[UIView animateWithDuration:10 animations:^{
self.completeImage.alpha = 1.0;
self.completeImage.alpha = 0.5;
self.completeImage.alpha = 0.0;
}];
Any ideas?
Thanks.
That is not working because automatically it sets the alpha to 0.0;
The 3 lines of code are executed at the same time (one after the other).
The proper way to use the UView animation block it is like this:
self.completeImage.alpha = 0.0;
[UIView animateWithDuration:2.0
animations:^{
// do first animation
self.completeImage.alpha = 1.0;
}
completion:^(BOOL finished){
[UIView animateWithDuration:2.0
animations:^{
// do second animation
self.completeImage.alpha = 0.0;
}
completion:^(BOOL finished){
;
}];
}];
Hope this achieve what you are looking for.
In addition:
" I'm trying to use so when a button is pressed a graphic appears
then slowly fades out (i.e. alpha is set to 0)."
As per your above information in the question, addition of the code in viewDidLoad will not prove fruitful. You need to add this code in the action target method of your button in order to play the animation on click of a button. Generally if you're using the nib, then the action method will be like below:
-(IBAction)on_pressing_my_button:(id)sender
{
///your animation code goes here..
}

Weird behaviour happens when using UIView animate and CGAffineTransform

I created some animations in my project. Basically, I use UIView animate and CGAffineTransform, but a very strange thing happened and I have no idea. Hope someone can help me solve this problem. Thanks in advance.
This is the strange thing:
After the user clicks on a button, the button slides off screen and another two buttons slide on the screen (I just changed the center point of these buttons to achieve this animation). And, some time later, a view on the screen start shaking (I use CGAffineTransform to achieve this).
At this moment, the strange thing happens - the button that previous slid off screen show up at its original position again and the other two buttons disappear (No animation, just shows up and disappear).
The following is the related code,
1) Button slide off and slide in animation related code
- (IBAction)start:(id)sender
{
// 1. Slide in cancel and pause button
[UIView animateWithDuration:0.5f animations:^{
[startButton setCenter:CGPointMake(startButton.center.x + 300.0f, startButton.center.y)];
[cancelButton setCenter:CGPointMake(cancelButton.center.x + 300.0f, cancelButton.center.y)];
[pauseButton setCenter:CGPointMake(pauseButton.center.x + 300.0f, pauseButton.center.y)];
} completion:^(BOOL finished) {
if (finished) {
NSLog(#"Move finished");
}
}];
}
2) The view shaking animation related code
- (void)shakeView:(UIView *)viewToShake
{
CGFloat t = 2.0;
CGAffineTransform translateRight = CGAffineTransformTranslate(CGAffineTransformIdentity, t, 0.0);
CGAffineTransform translateLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -t, 0.0);
viewToShake.transform = translateLeft;
[UIView animateWithDuration:0.07 delay:0.0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{
[UIView setAnimationRepeatCount:2.0];
viewToShake.transform = translateRight;
} completion:^(BOOL finished) {
if (finished) {
[UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
viewToShake.transform = CGAffineTransformIdentity;
} completion:nil];
}
}];
}
This isn't weird, it's a common problem with
auto layout. If you move UI elements by changing frames, then as soon as something else takes place that requires laying out views, the moved views will revert to the position defined by their constraints. To fix it, you either need to turn off auto layout, or do your animations by changing constraints not frames.
I have tried your code in my test project. The problem is probably because you are using Autolayout in your xib.
Please checking your xib file and uncheck the Autolayout property.

Animate image location different after returning to page

I have a tabbed application for iPad. On the first tab I have a separate menu with a pointer that highlights the currently active menu button. The pointer (a UIImage) is animated into position after tapping the button.
The problem is when you leave the highlighted image on any button that's not the original/default button and move to another tab in the application, then back again, the image has moved back to the default location. However, when you tap another button the image moves in the wrong direction. I think it's because the image moves back but the old coordinates are retained, or the other way around? It's a bit hit and miss and behaves differently testing in the simulator compared to directly on the iPad.
I think I need to start with absolute coordinates and stick with them throughout the process. But I can't get my head around how to achieve it with the CGAffine functions.
Here is my current code
- (IBAction)diplayForm1:(id)sender {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
buttonHighlightImage.transform = CGAffineTransformMakeTranslation(0, 0);
[UIView commitAnimations];
}
- (IBAction)diplayForm2:(id)sender {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
buttonHighlightImage.transform = CGAffineTransformMakeTranslation(0, 80);
[UIView commitAnimations];
}
- (IBAction)diplayForm3:(id)sender {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
buttonHighlightImage.transform = CGAffineTransformMakeTranslation(0, 160);
[UIView commitAnimations];
}
EDIT - - -
#Mundi I tried the code you suggested. I'm assuming by newFrame you mean define a new UIImageView and property which I did in the .h (I called it 'sfh'), then #synthesize in the .m.
This is my code in the .m
-(void)viewWillAppear:(BOOL)animated {
// The "pointer" and the "old" frame are the same so I thought it pointless to do
// selectedFormHighlight.frame = selectedFormHighlight.frame;
// I tried anyway and also tried this and many other combinations
selectedFormHighlight.frame = sfh.frame;
}
-(void)viewDidAppear:(BOOL)animated {
[UIView beginAnimations:nil context:NULL];
[UIView animateWithDuration:0.3 animations:^{
selectedFormHighlight.frame = CGRectMake(0,0,0,0);
}];
[UIView commitAnimations];
}
When I run this the pointer animates off the screen (top-left) and doesn't come back. I have tried every possible combination I can think of in viewWillAppear and viewDidAppear but it makes no difference. I tried removing the other lines in viewDidAppear and it still does the same thing.
I think you're suggesting to animate the pointer from the original (default) position when the user returns from another screen. I don't want that, it should simply remain in the same spot where they left it without animation. Or at least put it back there without them realizing it. The only animation is when they choose to tap a different button within that view.
The reason you are experiencing this is that the actual view object and its presentation layer get mixed up when the view is hidden and redisplayed. The solution is to change the view properties rather than animate the layers.
Thus, you do not need to use affine transforms. Just set the new position of the pointer view directly by changing its frame or center.
The more up-to-date format to do this is with block based animations:
[UIView animateWithDuration:0.5 animations:^{
pointer.frame = newFrame;
}];
Also, it seems very inefficient to have three methods just differing by one variable. You could just multiply the desired y position by 80.
Edit:
Another reason your button resets is because that is where it was put when the view is instantiated. Just set the position of your view in viewWillAppear of your view controller and then animate it to the new location in viewDidAppear.
I appreciate the help from #Mundi but couldn't get it to work that way. I eventually arrived at the following code.
// This initially sets the frame with a variable value that
// corresponds to the current child view
-(void)viewDidAppear:(BOOL)animated {
selectedFormHighlight.frame = CGRectMake(0, self.getY, 250, 4100);
}
// Button actions (converted to a single action instead of one for each button)
// This was done by referencing a tag added to each button (the button tags
// match the children's tags)
-(IBAction)goToForm:(id)sender {
UIButton *btn = (UIButton *)sender;
self.currentChild = self.formViewControllers[btn.tag];
[UIView beginAnimations.nil context:NULL];
[UIView animateWithDuration:0.3 animations:^{
selectedFormHighlight.frame = CGRectMake(0, self.getY, 250, 4100);
}];
[UIView commitAnimations];
sfh.frame = selectedFormHighlight.frame;
}
// This returns the 'y' (vertical center position) of the pointer
// frame for each of the child views
-(int)getY {
switch(_currentChild.view.tag) {
case 1:
return -2005;
break;
case 2:
return -1925;
break;
default:
return -1845;
break;
}
}

UIButton does not clip its imageView when it's highlighted

I want to create an effect where a button's image slides in / out of button rect, the final effect should look like this:
sliding buttons
So the first one just started it's "transition", the second is half way through and the last one is fully slided out.
To achieve this, I set the button's clipsToBounds property to YES and then animate button's imageView:
- (void)setupButtons
{
self.buttonsYOffset = -60.0;
self.buttonsOriginalY = self.twitterButton.imageView.center.y;
self.twitterButton.clipsToBounds = YES;
self.twitterButton.imageView.center = CGPointMake(self.twitterButton.imageView.center.x, self.buttonsOriginalY + self.buttonsYOffset);
}
and:
- (void)show
{
[UIView animateWithDuration:0.2 delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^ {
self.twitterButton.imageView.alpha = 1.0;
self.twitterButton.imageView.center = CGPointMake(self.twitterButton.imageView.center.x, self.buttonsOriginalY);
}
completion:^(BOOL success) {
}
];
}
- (void)hide
{
[UIView animateWithDuration:0.2 delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^ {
self.twitterButton.imageView.center = CGPointMake(self.twitterButton.imageView.center.x, self.buttonsOriginalY + self.buttonsYOffset);
}
completion:^(BOOL success) {
}
];
}
Everything works fine if I fire this code when button is in "inactive" state (not tapped) - it slides in and out just fine.
The problem starts when I fire hide() method immediately after button has been tapped - It does not slide out then - just highlights for a second, and it's image stays in "opened" position for a while, then skips to "closed" position immediately.
It seems that button's imageView is used only when button is in its default inactive state? Can it be easily fixed?

How to cross-fade a UIScrollView back to the beginning

I have a horizontally-scrolling paging UIScrollView in an iPad app, containing lots of pages. On the last page, I tap on a button on the screen to reset back to page 1. I would like to be able to cross-dissolve this transition, but it doesn't seem to work:
[UIView transitionWithView:self.view duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationOptionAllowAnimatedContent animations:^{
pagingScrollView.contentOffset = CGPointZero;
} completion:^(BOOL finished) {
[self refreshPages];
}];
I read that adding UIViewAnimationOptionAllowAnimatedContent will allow all content to transition, but it doesn't work. Instead, the screen cross-dissolves to the background colour, and when the transition is complete, the first page just appears.
you cannot fade-out a UIView (the scroller) AND simultaneously fade-in the same view...
you could just using different UIViews...
what you can do is:
1) fadeOut the scroller in the current position (to the backGround)
2) while the scroller is invisible, move it to the right position (with no animation)
3) fadeIn the scroller from the backGround
something like:
// START FIRST PART OF ANIMATION
[UIView animateWithDuration:0.5 delay:0.0 options: options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationOptionAllowAnimatedContent animations:^{
pagingScrollView.alpha = 0;
} completion:^(BOOL finished) {
// FIRST PART ENDED
// MOVE SCROLLER (no animation)
pagingScrollView.contentOffset = CGPointZero;
// START SECOND PART OF ANIMATION
[UIView animateWithDuration:0.5 delay:0.0 options: options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationOptionAllowAnimatedContent animations:^{
// fadeIn - animated
pagingScrollView.alpha = 1;
} completion:^(BOOL finished) {
// ANIMATION ENDED
[self refreshPages];
}];
}];
NEW EDIT:
thanks to amadour, who taught me something with his comments,
i hope he could add an answer of his own, i would vote for him
anyway, to answer to jowie original question:
i got the right animation just moving the contentOffset setting out of the animation block,
and removing UIViewAnimationOptionAllowAnimatedContent (not really needed), and passing pagingScrollView as parameter for transitionWithView
this worked for me:
pagingScrollView.contentOffset = CGPointZero;
[UIView transitionWithView:pagingScrollView duration:3.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
// pagingScrollView.contentOffset = CGPointZero; // move up, outside of animation block
} completion:^(BOOL finished) {
NSLog(#"-->> END amimation");
[self refreshPages];
}];

Resources