Make shake effect for label in ios? - ios

Am working with shake effect for label i called the animation while pressing cell in tableview but it is not working.if i call animation in cellForRowAtIndexPath:(NSIndexPath *)indexPath it is working but if i cal it in didSelectRowAtIndexPath:(NSIndexPath *)indexPath it is not working. could any one help me??? thanks in advance
-(void)shakeAnimation:(UILabel*) label {
const int reset = 5;
const int maxShakes = 6;
//pass these as variables instead of statics or class variables if shaking two controls simultaneously
static int shakes = 0;
static int translate = reset;
[UIView animateWithDuration:0.09-(shakes*.01) // reduce duration every shake from .09 to .04
delay:0.01f//edge wait delay
options:(enum UIViewAnimationOptions) UIViewAnimationCurveEaseInOut
animations:^{label.transform = CGAffineTransformMakeTranslation(translate, 0);}
completion:^(BOOL finished){
if(shakes < maxShakes){
shakes++;
//throttle down movement
if (translate>0)
translate--;
//change direction
translate*=-1;
[self shakeAnimation:label];
} else {
label.transform = CGAffineTransformIdentity;
shakes = 0;//ready for next time
translate = reset;//ready for next time
return;
}
}];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self shakeAnimation:cell.MyHomeMenuCountlabel];
}

use this code for shake animation for views
-(void)shakeAnimation:(UILabel*) label
{
CABasicAnimation *shake = [CABasicAnimation animationWithKeyPath:#"position"];
[shake setDuration:0.1];
[shake setRepeatCount:5];
[shake setAutoreverses:YES];
[shake setFromValue:[NSValue valueWithCGPoint:
CGPointMake(label.center.x - 5,label.center.y)]];
[shake setToValue:[NSValue valueWithCGPoint:
CGPointMake(label.center.x + 5, label.center.y)]];
[label.layer addAnimation:shake forKey:#"position"];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell cell = [theTableView cellForRowAtIndexPath:theIndexPath];
UILabel label=(UILabel*)[cell.contentView viewWithTag:2001];
[self shakeAnimation:label];
}

There are 2 ways to do this :
1.Try this function :
NSArray *arrIndexPath = [NSArray arrayWithObject:indexPath];
[dropTable reloadRowsAtIndexPaths:arrIndexPath withRowAnimation:UITableViewRowAnimationFade];
in didSelectRowAtIndexPath function.
Make animation in cellForRowAtIndexPath only.
2.Assign a tag property to your cell in cellForRowAtIndexPath.
cell.tag = indexPath.row.
In didSelectRowAtIndexPath :
Then using subviews of table, get the cell.tag equal to indexPath.row and taking the reference of same cell and then do animation:
for (MyHomeViewCell *cell in [table subviews]) { // change name of table here
if ([cell isKindOfClass:[MyHomeViewCell class]]) {
if (cell.tag == indexPath.row) {
[self shakeAnimation:cell.MyHomeMenuCountlabel];
}
}
}

Finlay i got you solution hope this may Helps you. For shake particular Label you can add UITapGestureRecognizer for getting Particular UILabel tap and set Shake animation into UITapGestureRecognizer's #selector method like Bellow example:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
UILabel *cellTitle=[[UILabel alloc]initWithFrame:CGRectMake(100, 7, 300, 30)];
cellTitle.userInteractionEnabled = YES;
cellTitle.tag = indexPath.section;
[cellTitle setBackgroundColor:[UIColor clearColor]];
[cellTitle setFont:[UIFont fontWithName:#"Helvetica" size:14]];
[cellTitle setText:_objects[indexPath.row]];
[cellTitle setTextColor:[UIColor blackColor]];
[cell.contentView addSubview:cellTitle];
UITapGestureRecognizer *labelTap = [[UITapGestureRecognizer alloc] init];
[labelTap addTarget:self action:#selector(viewPatient:)];
[labelTap setDelegate:nil];
[labelTap setNumberOfTapsRequired:1];
[cellTitle addGestureRecognizer:labelTap]; // cellTitle add here
[labelTap release];
return cell;
}
-(void)viewPatient:(id)sender
{
UILabel *lObjLabel = (UILabel *)[sender view];
CGFloat t = 2.0;
CGAffineTransform translateRight = CGAffineTransformTranslate(CGAffineTransformIdentity, t, 0.0);
CGAffineTransform translateLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -t, 0.0);
lObjLabel.transform = translateLeft;
[UIView animateWithDuration:0.07 delay:0.0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{
[UIView setAnimationRepeatCount:10];
lObjLabel.transform = translateRight;
} completion:^(BOOL finished) {
if (finished) {
[UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
lObjLabel.transform = CGAffineTransformIdentity;
} completion:NULL];
}
}];
}
It code working like:-

use this function
- (void)shakeView:(UIView *)viewToShake
and write down any animation code you want in this function and call it from where you want to animate you item
and if you choose first animation then also use following code piece too this function is used to finish animation properly
#define RADIANS(degrees) ((degrees * M_PI) / 180.0)
- (void) wobbleEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
UIView* item = (__bridge UIView *)context;
item.transform = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(90.0));
}
and here are two type of animation chose whatever you want
1. shake animation like deleting a pp from ipad or iphone and decide shaking by proper angle
CGAffineTransform leftWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(88.0));
CGAffineTransform rightWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(92.0));
viewToShake.transform = leftWobble; // starting point
[UIView beginAnimations:#"wobble" context:(__bridge void *)(viewToShake)];
[UIView setAnimationRepeatAutoreverses:YES]; // important
[UIView setAnimationRepeatCount:2000];
[UIView setAnimationDuration:0.25];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(wobbleEnded:finished:context:)];
viewToShake.transform = rightWobble; // end here & auto-reverse
[UIView commitAnimations];
2.normal shake animation
CGFloat t = 2.0;
CGAffineTransform translateRight = CGAffineTransformTranslate(CGAffineTransformIdentity, 85, 0.0);
CGAffineTransform translateLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, 95, 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 = CGAffineTransformTranslate(CGAffineTransformIdentity, 95, 0.0);
} completion:NULL];
}
}];
}

Related

Animation of scrolling in collectionview in ios

I have one one collectionview in that I have 10 images loaded from webservice. I want to autoscroll that imageview from 1st to last position and then last to 1st position continuously whenever that page appears.
I use below method
-(void)scrollSlowly
{
CATransition *transition = [CATransition animation];
transition.duration = 4.0f;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[UIView animateWithDuration:5.0f
delay:3.0f
options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^{
[self.CollectionView setContentOffset:CGPointMake(CGFLOAT_MAX ,0)];
}
completion:nil];
[self.CollectionView.layer addAnimation:transition forKey:#"transition"];
}
-(void)scrollSlowlyToPoint
{
self.CollectionView.contentOffset = self.scrollingPoint;
// Here you have to respond to user interactions or else the scrolling will not stop until it reaches the endPoint.
if (CGPointEqualToPoint(self.scrollingPoint, self.endPoint))
{
[self.scrollingTimer invalidate];
}
// Going one pixel to the right.
self.scrollingPoint = CGPointMake(self.scrollingPoint.x+1, self.scrollingPoint.y);
}
I want to autoscroll horizontally in Objective-C. thanks in advance
Create a custom UICollectionViewCell class, create and connect an outlet for image view.
In .h file:
NSMutableArray *imgArr;
NSInteger testIndexPath;
I guess you can implement the datasource methods for UICollectionView.
In cellForItemAtIndexPath add this line after adding images to the imageview
testIndexPath=indexPath.row;//this will give you the indexPath for cell
Now add this two methods in your .m file:
-(void)autoScroll{
CGFloat point = self.collectionVw.contentOffset.x;
CGFloat lo = point + 1;
[UIView animateWithDuration:0 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.collectionVw.contentOffset = CGPointMake(lo, 0);
}completion:^(BOOL finished){
if (testIndexPath==8)
{
[self autoScrollReverse];
}
else{
[self autoScroll];
}
}];
}
-(void)autoScrollReverse{
CGFloat point = self.collectionVw.contentOffset.x;
CGFloat lo = point - 1;
[UIView animateWithDuration:0 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.collectionVw.contentOffset = CGPointMake(lo, 0);
}completion:^(BOOL finished){
if(testIndexPath == 0){
[self autoScroll];
}else{
[self autoScrollReverse];
}
}];
}
//Call [self autoScroll] in your viewDidLoad
Better way to scroll index from top to bottom and bottom to top.
This will move to index 10 means scroll top to bottom
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:9 inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
For again scroll bottom to top which move to index 0
[UIView animateWithDuration:3
delay:0.1
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
}
completion:nil];
You can also set scrolling from top to bottom in UIVIew animation like above.
Set the first method in ViewWillAppear and set second method in ViewDidAppear if you need animation for every time page appear
Please apply this one. May be its help to you
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MyCollectionViewCell" forIndexPath:indexPath];
[UIView animateWithDuration:0.2 animations:^{
cell.transform = CGAffineTransformMakeTranslation(0.0, -50);
}];
[self delayBy:0.5 code:^{ // call block of code after time interval
[UIView animateWithDuration:0.3 animations:^{
cell.transform = CGAffineTransformIdentity;
}];
}];
return cell;
}
This may help solve your problem:
int maxDelay = 4;
int delayInSeconds = arc4random() % maxDelay;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//your codes//
});

Bounce Animation on UITableViewCell

When the UITableView loads I want its first cell to bounce from the Right side, so It indicates the User that they can swipe right to delete a cell.
How can I do this ?
My code so far:
note: In the following code I am just making the cell to blink, but what I actually want is the cell to bounce.
-(void) tableView:(UITableView *) tableView willDisplayCell:(UITableViewCell *) cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
//row number on which you want to animate your view
//row number could be either 0 or 1 as you are creating two cells
//suppose you want to animate view on cell at 0 index
if(indexPath.row == 0) //check for the 0th index cell
{
// access the view which you want to animate from it's tag
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:1];
UIView *myView = [self.tableView cellForRowAtIndexPath:indexPath];
NSLog(#"row %ld",(long)indexPath.row);
// apply animation on the accessed view
[UIView animateWithDuration:5
delay:2
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut animations:^
{
[myView setAlpha:0.0];
} completion:^(BOOL finished)
{
[myView setAlpha:1.0];
}];
}
}
If I understand this correctly, you wish to bounce the cell from left to right?
Get a reference to the cell's contentView:
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:1];
UIView *contentView = [self.tableView cellForRowAtIndexPath:indexPath].contentView;
Now there are many ways to 'bounce' this contentView. One way would be to use an animation block like this:
CGRect original = contentView.frame;
CGRect bounce_offset = original;
original.origin.x -= 100.0f;
What we do here, is remember the original frame, and decide how far we want our bounce to reach in the animation block. Then we can animate for example doing something like this:
[UIView animateWithDuration:0.5f delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
contentView.frame = bounce_offset;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{
contentView.frame = original;
} completion:^(BOOL finished) {
}];
}]
You could also use autoreverse options, this 'a' way to do it though. Let me know what your thoughts are!

TableView not animating

I want to animate UIView simultaneously. But my UIView is not animated. Side over lap But my UITableView is not animated.
[self.view addSubview:sideview];
[sidevieww setHidden:NO];
[UIView animateWithDuration:0.3 animations:^{
[sidevieww setFrame:CGRectMake(0, 0, sidevieww.frame.size.width, sidevieww.frame.size.height)];
[mytable setFrame:CGRectMake(240,mytable.frame.origin.y,mytable.frame.size.width,mytable.frame.size.height)];
[mynav setFrame:CGRectMake(240,mynav.frame.origin.y,mynav.frame.size.width,mynav.frame.size.height)];
[mybutton setFrame:CGRectMake(240, mybutton.frame.origin.y, mybutton.frame.size.width, mybutton.frame.size.height)];
} completion:^(BOOL finished) {
sideview =true;
}];
That is really not the best way to configure frame.
Replace your code by this one:
[self.view addsubview:sideview];
[sidevieww setHidden:NO];
CGRect frameSideVieww = sidevieww.frame;
frameSideVieww.origin.x = frameSideVieww.origin.y = 0;
CGRect frameMyTable = mytable.frame;
frameMyTable.origin.x = 240;
CGRect frameMyNav = mynav.frame;
frameMyNav.origin.x = 240;
CGRect frameMyButton = mybutton.frame;
mybutton.origin.x = 240;
[UIView animateWithDuration:0.3 animations:^{
[sidevieww setFrame:frameSideVieww];
[mytable setFrame:frameMyTable];
[mynav setFrame:frameMyNav];
[mybutton setFrame:frameMyButton];
}completion:^(BOOL finished) {
sideview =true;
}];
Also, check if your class is subclass of UIViewController.

Image in a cell shows above textLabel and detailTextLabel but under accessory view

So I have a UIImageView as a subview in a UITableViewCell. I wish it to be above everything in the cell (thus, user cannot see anything that is covered by this imageView). However, it only covers the textLabel and the detailTextLabel, but not the accessoryView. Can anyone tell me how to do this? Thanks a lot.
Here's some code:
When initializing the cell, I have
[cell setAccessoryView:rangeIndicatorView];
And when I add an imageView on top of it,
-(void) animateSwipeOnCell:(UITableViewCell*)cell {
UIImageView *swipeImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"swipe_arrow.png"]];
[cell.contentView addSubview:swipeImg];
[swipeImg setFrame:CGRectMake(cell.bounds.origin.x - cell.bounds.size.width, cell.bounds.origin.y, cell.bounds.size.width, cell.bounds.size.height)];
[UIView animateWithDuration:1
delay:0.3
options:UIViewAnimationOptionCurveLinear
animations:^{
[swipeImg setFrame:CGRectMake(cell.bounds.origin.x + cell.bounds.size.width, cell.bounds.origin.y, cell.bounds.size.width, cell.bounds.size.height)];
}
completion:^(BOOL finished) {
[swipeImg removeFromSuperview];
}];
}
I couldn't make it work by adding the image directly to the UITableViewCell, so here's an alternative, by putting the view directly on the UITableView:
- (void)animateSwipeOnTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath {
UIImageView *swipeImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"swipe_arrow.png"]];
CGRect tableViewRect = [tableView rectForRowAtIndexPath:indexPath];
[tableView addSubview:swipeImg];
[swipeImg setFrame:CGRectMake(tableViewRect.origin.x - tableViewRect.size.width, tableViewRect.origin.y, tableViewRect.size.width, tableViewRect.size.height)];
[UIView animateWithDuration:1
delay:0.3
options:UIViewAnimationOptionCurveLinear
animations:^{
[swipeImg setFrame:CGRectMake(tableViewRect.origin.x + tableViewRect.size.width, tableViewRect.origin.y, tableViewRect.size.width, tableViewRect.size.height)];
}
completion:^(BOOL finished) {
[swipeImg removeFromSuperview];
}];
}

Text Animation within didSelectRowAtIndexPath:?

I'm using an MCSwipeTableViewCell so the idea is that the user swipes it left or right to complete actions. However the user may not always be familiar with this action so when they tap the cell (expecting to select it) I want the text to briefly flash a short instruction then return to the original text.
I've been on this for days and keep coming back to it with no luck. I've tried using the completion block, playing about with the delays, all sorts but the animation seems to complete so quickly you don't actually see the change, what am I doing wrong?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
MCSwipeTableViewCell *cell = (MCSwipeTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
Station *station = self.recentStations[indexPath.row];
[UIView animateWithDuration:0.5 animations:^{
//code to fade the text out
CATransition *animation = [CATransition animation];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.type = kCATransitionFade;
animation.duration = 0.35;
[cell.textLabel.layer addAnimation:animation forKey:#"kCATransitionFade"];
//instructions to appear briefly
cell.textLabel.text = #"Swipe left to set alarm or right to remove";
//nested animation to revert text after a 1.5 second delay
[UIView animateWithDuration:.05 delay:1.5 options:UIViewAnimationOptionCurveEaseIn animations:^{
//code to fade the text back in
CATransition *animation = [CATransition animation];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.type = kCATransitionFade;
animation.duration = 0.35;
[cell.textLabel.layer addAnimation:animation forKey:#"kCATransitionFade"];
cell.textLabel.text = station.name;
} completion:nil];
}];
}
You're using duplicate nested animation APIs. Give the below code a try.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
MCSwipeTableViewCell *cell = (MCSwipeTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
Station *station = self.recentStations[indexPath.row];
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
cell.textLabel.alpha = 0.0f;
} completion:^(BOOL finished) {
//instructions to appear briefly
cell.textLabel.alpha = 1.0f;
cell.textLabel.text = #"Swipe left to set alarm or right to remove";
[UIView animateWithDuration:0.5 delay:1.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
cell.textLabel.alpha = 0.0f;
} completion:^(BOOL finished) {
cell.textLabel.alpha = 1.0f;
cell.textLabel.text = station.name;
}];
}];
}
That code will have the new text instantaneously swap out the old text and appear - you can probably figure out how to add more animations to prevent this if desired.

Resources