I trying to create activity indicator, currentView will be static and nextView will animate left to right, right to left, top to bottom and bottom to top.
I had written the code as below. The problem I am facing is, instead of all the four animations I am getting only one animation top to bottom animation. Can anyone help me how to run all the four animations one by one until a process is completed
statusImage = [UIImage imageNamed:#"image2.png"];
moveImage = [UIImage imageNamed:#"image1.png"];
currentView = [[UIImageView alloc]
initWithImage:statusImage];
nextView = [[UIImageView alloc]
initWithImage:moveImage];
//Add your custom activity indicator to your current view
[self.view addSubview:currentView];
[self.view addSubview:nextView];
CATransition *transition1 = [CATransition animation];
[transition1 setType:kCATransitionPush];
[transition1 setSubtype:kCATransitionFromLeft];
[transition1 setDuration:1];
[nextView.layer addAnimation:transition1 forKey:#"string1"];
CATransition *transition2 = [CATransition animation];
[transition2 setType:kCATransitionPush];
[transition2 setSubtype:kCATransitionFromRight];
[transition2 setDuration:1];
[nextView.layer addAnimation:transition2 forKey:#"string2"];
CATransition *transition3 = [CATransition animation];
[transition3 setType:kCATransitionPush];
[transition3 setSubtype:kCATransitionFromTop];
[transition3 setDuration:1];
[nextView.layer addAnimation:transition3 forKey:#"string3"];
CATransition *transition4 = [CATransition animation];
[transition4 setType:kCATransitionPush];
[transition4 setSubtype:kCATransitionFromBottom];
[transition4 setDuration:1];
[nextView.layer addAnimation:transition4 forKey:#"string4"];
Can anyone help me how to run all the four animations one by one until a process is completed
A layer can have only one transition animation at a time. There is no point supplying a key for a transition animation. The key will always really be kCATransition. Your string1 etc. are pointless; just use nil. Moreover, your code makes no sense; multiple animations attached to a layer causes those animations to be performed simultaneously (if possible), not successively.
You need to chain the animations. Set up your code like this:
Perform the first animation, giving it a completion handler. This completion handler is called when the first animation finishes.
In the completion handler, do the second animation, giving it a completion handler. This completion handler is called when the second animation finishes.
In the completion handler, do the third animation, giving it a completion handler. This completion handler is called when the third animation finishes.
In the completion handler, do the fourth animation.
Related
I have a problem when I want to create a transition between to views inside a container view in iOS application. I want to create an animation that makes my first view goes out sliding to the left and the second coming from the right (like switching between photos, a sort of push in Navigation Controller). I created my animation but the problem is that my subview does not disappear once reached the border of my container view but when it reaches the edge of my screen.
I used this code:
CATransition *transition = [CATransition animation];
transition.duration = animationTime;
transition.type = kCATransitionPush;
transition.subtype = transationSubtype;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
transition.removedOnCompletion = YES;
[view.layer addAnimation:transition forKey:nil];
As visible in the image the red square goes out from the screen and not from its container and also the green comes inside from the screen edge and not from the container view edge. I want instead that the animation ends when reaches the container view edge.
I tried anything but I was not able to find something useful.
Try to set clipsToBounds property of the container view to YES
I have a UIImageView in the center of the screen (Position Set with the help of the constraints through the storyboard)
In the code's viewDidLoad method I set the image for that imageView by:
self.imageView.image = [UIImage imageNamed:#"food"];
Then I wanted to slide the old image off from left of the UIImageView and slide the new image on from right of the UIImageView for which i have used the following code(The code below is triggered after the swipe gesture is recognized, so the code below is inside the selector method for the swipeGestureRecognizer):
self.imageView.image = [UIImage imageNamed:#"picnic"];
CATransition *animation = [CATransition animation];
[animation setDuration:1];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[self.imageView layer] addAnimation:animation forKey:nil];
But when I do this the new image appears on the screen from the right edge of the screen and not the right edge of the UIImageView and same with the old image which is pushed out all the way to the left edge of the screen and not the left edge of the UIImageView.
Is there a way I can fix it?
Any help would be appreciated. Thanks
You can try put image view into view which too have clip to bounds YES. I think this should help.
I'm working on and iPhone app, and have an issue with a gesture recognizer.
I've added an UITapGestureRecognizer on a view, then I transform the layer related to this view with CABasicAnimation. After this transformation, the gesture recognizer only works in the area occupied by the view before the transformation.
Hope this little description of my problem is understandable..
Here is some code :
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myViewTapped:)];
[self.myView addGestureRecognizer:tapGestureRecognizer];
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:#"position.y"];
[animation setFromValue:[NSNumber numberWithFloat:0]];
[animation setToValue:[NSNumber numberWithFloat: - 100]];
[animation setDuration:.3];
[animation setTimingFunction:[CAMediaTimingFunction functionWithControlPoints:.55 :-0.25 :.30 :1.4]];
animation.additive = YES;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[self.myView.layer addAnimation:animation forKey:nil];
How can I handle this issue ?
Thanks !
You are animating only the graphical part of the view (the CALayer), not the part responsable for user interaction (the UIView itself).
Your code move the layer and made it been drown elsewhere, but don't change the frame (or the bound+center).
You have 3 option (well maybe more, just I can think of these 3):
1) use the UIView-based animations [UIView animation...]
2) struct with you code but also relocare the view after the animation take place (but this may rise issues cause your layer will be moved also).
3) use your animation but put the gesture recognizer on a parent (bigger) view and then check the events there...
I have implemented nested UITableViews such that, on selecting a particular row from parent Data list, gets child nodes data from server and reloads them in same UITableview. I have given provision to go back to parent nodes using dictionary and everything working fine. I want Navigation Style animation when I move parent data list to child data list. Could someone please help me how to do this.
I have tried using following code UIViewAnimationOptionTransitionFlipFromLeft and UIViewAnimationOptionTransitionFlipFromRight animations it flips the view - I am looking for similar but without flip - simple navigation style animation like I want to pretend I am pushing another UITableView.
[UIView transitionWithView: self.listTableView
duration: 0.35f
options: UIViewAnimationOptionTransitionFlipFromLeft
animations: ^(void) {
[self.listTableView reloadData];
} completion: ^(BOOL isFinished){
}];
Here is Logic with Code.
you need to import QuartzCore framework in.h` for using below piece of Code.
AS #import
// Method to replace a given subview with another using a specified transition type, direction, and duration
-(void)replaceSubview:(UIView *)oldView withSubview:(UIView *)newView transition:(NSString *)transition direction:(NSString *)direction duration:(NSTimeInterval)duration
{
// Set up the animation
CATransition *animation = [CATransition animation];
// Set the type and if appropriate direction of the transition,
if (transition == kCATransitionFade)
{
[animation setType:kCATransitionFade];
}
else
{
[animation setType:transition];
[animation setSubtype:direction];
}
// Set the duration and timing function of the transtion -- duration is passed in as a parameter, use ease in/ease out as the timing function
[animation setDuration:duration];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[oldView layer] addAnimation:animation forKey:#"transitionViewAnimation"];
}
Call Above method when TableView row gets Clicked as below.
[self replaceSubview:thisTableView
withSubview:thisTableView
transition:kCATransitionPush
direction:kCATransitionFromLeft
duration:0.3];
//thisTableView is instance of UItableView.
I have a simple animation setup in a Mac App where a page control swaps out some views. I am very close to getting the paging-like animation I want, but there is a slight problem. The paging works and the new page animates into place correctly, but the new page also replaces the initial page before the animation. I wish to ultimately have the view that is being pushed out remain the same instead of changing to the new page early. Here is a video showing the problem, slowed down to a 3 second animation duration. Here is the code:
UASourceView *previousSourceView = [self.sourceViewContainer.subviews objectAtIndex:0];
NSInteger previousIndex = [self.sourceViews indexOfObjectIdenticalTo:previousSourceView];
CATransition *pushTransition = [CATransition animation];
[pushTransition setType:kCATransitionPush];
[pushTransition setSubtype:(previousIndex < index) ? kCATransitionFromRight : kCATransitionFromLeft];
[pushTransition setDuration:PANEL_PAGE_SWIPE_ANIMATION_DURATION];
[pushTransition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[pushTransition setRemovedOnCompletion:YES];
[CATransaction begin];
[self.sourceViewContainer replaceSubview:previousSourceView with:sourceView];
[CATransaction commit];
[sourceView.layer addAnimation:pushTransition forKey:#"push"];
There is a fixed container view self.sourceViewContainer that gets a new subview replaced on every animation. The problem, as seen above is that the previousSourceView gets replaced immediately by the sourceView and gets pushed in as well. Please help me stop the immediate replacement. Where am I going wrong?
*Note, iOS tag is added because this code is platform independent.
I solved similar issues using CAAnimationBlocks (this is my fork of the original, which the author has moved in a direction I didn't much care for).
The idea is to set removedOnCompletion to NO and fillMode to kCAFillModeForwards and perform the actual switch (without animation) in the completion block. This has been tested under OSX only (you might need a different solution for iOS, which already supports completion blocks).
Here's an example usage from my code, which moves a piece on a chess board, and back again:
CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:#"position"];
moveAnimation.fromValue = [NSValue valueWithPoint:[self _pointForSquare:move.from()]];
moveAnimation.toValue = [NSValue valueWithPoint:[self _pointForSquare:move.to()]];
moveAnimation.duration = _animateSpeed / 1000.0;
moveAnimation.autoreverses = YES;
moveAnimation.removedOnCompletion = NO;
moveAnimation.fillMode = kCAFillModeForwards;
moveAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
moveAnimation.completion = ^(BOOL finished)
{
[pieceLayer removeAnimationForKey:#"movePiece"];
[self _setPieceLayer:pieceLayer toPiece:piece];
[pieceLayer setNeedsDisplay];
};
[pieceLayer addAnimation:moveAnimation forKey:#"movePiece"];