Control the speed of uitableview insertRowsAtIndexPath animations - ios

I used insertRowsAtIndexPath instead of reloadData.
On the first loading, the animation is too fast because the number of rows is high.
Can I control the speed animation of insertRowsAtIndexPath ?
Thanks.

I think it's not possible to manipulate the animation speed.
Maybe you can use scrollToRowAtIndesPath instead.

Override the insertRowsAtIndexPaths and add custom animation as you like with delay.
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation
{
for (NSIndexPath *indexPath in indexPaths)
{
UITableViewCell *cell = [self cellForRowAtIndexPath:indexPath];
[cell setFrame:CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
[UIView beginAnimations:NULL context:nil];
[UIView setAnimationDuration:1];
[cell setFrame:CGRectMake(0, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
[UIView commitAnimations];
}
}

Absolutely untested, but you could try this for a five-seconds animation:
[UIView animateWithDuration:5. animations:^(void){
[_tableView insertRowsAtIndexPath:... animated:NO];
}];

Related

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!

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];
}];
}

animating UITableViewHeader to grow/shrink

Im very new to iOS and am trying to figure out how I can animate the tableView header to appear like its sliding down from the top of the view, stay there for 3 seconds, then slide back up and disappear.
I havent done any animation of any kind before so I could really use some help. I dont know where to start. Ive looked at other answers on here but cant seem to figure out how to do it.
ive got my table view appearing just fine with this code in my viewDidLoad of my UITableViewController class
self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320,15)];
self.headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 15)];
self.headerLabel.textAlignment = NSTextAlignmentCenter;
self.headerLabel.text = #"some text";
[self.headerView addSubview:self.headerLabel];
self.tableView.tableHeaderView = self.headerView;
self.tableView.tableHeaderView.frame = CGRectMake(0, 0, 320, 15);
I assume I need to animate the height of my frame.
edit: I found this code which seems like it should work, however it crashes my app when the animation runs
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[UIView animateWithDuration:3.0f
delay:0.0f
options: UIViewAnimationOptionBeginFromCurrentState
animations:^{
self.headerView.frame = CGRectMake(0.0f, 0.0f, 320.f, 0.0f);
}
completion:^(BOOL finished) {
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}];
}
I don't know if you can animate a table view's header view like you want to. With a complex UI object like a Table view Apple tends to treat the views that make up the object as private, and bad things tend to happen when you try to manipulate the view hierarch.
If you're not using auto-layout and you want to animate another view that is part of YOUR view hierarchy then your code might be as simple as something like this:
CGPoint center = myView.center;
CGFloat myViewBottom = myView.frame.origin.y + myView.frame.origin.size.height;
//Move the view above the top of it's superview before starting the animation.
center.y -= myViewBottom;
//Animate the view down into position
[UIView animateWithDuration: .2
animations:
^{
myView.center += myViewBottom;
};
completion:
^{
//As the completion block for the first animation, trigger another
//animation to animate the view away again. This time delay
//for 3 second before the 2nd animation.
[UIView animateWithDuration: .2
delay: 3.0
options: 0
animations:
^{
myView.center -= myViewBottom;
};
completion: nil
}
];
Try to use beginUpdates and endUpdates, here is an example:
in your header
#property NSInteger newOffset;
implementation:
- (void) colapseHeader
{
_newOffset = 50;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50 + _newOffset;
}
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
_newOffset = 100;
[self.tableView beginUpdates];
[self.tableView endUpdates];
[self performSelector:#selector(colapseHeader) withObject:nil afterDelay:3];
}

UITableView scroll animation on reload

I'm trying to animate the content of a tableview right after my data are reloaded.
I succeed by doing this:
[_tableView reloadData];
[_tableView setContentInset:UIEdgeInsetsMake(-_tableView.contentSize.height, 0, 0, 0)];
[UIView animateWithDuration:kAnimationDuration animations:^{
[_tableView setContentInset:UIEdgeInsetsMake(35, 0, 0, 0)];
[_tableView setContentOffset:CGPointMake(0.0f,-35.f)];
}];
But my animation has not the same speed on different content size (slower or faster).
How can adjust my speed and have exactly the same animation after each reload ?
Set animation duration in proportion to content size of your table view.
[_tableView reloadData];
[_tableView setContentInset:UIEdgeInsetsMake(-_tableView.contentSize.height, 0, 0, 0)];
animationDuration = _tableView.contentSize.height * aConstantK;
[UIView animateWithDuration:animationDuration animations:^{
[_tableView setContentInset:UIEdgeInsetsMake(35, 0, 0, 0)];
[_tableView setContentOffset:CGPointMake(0.0f,-35.f)];
}];

UICollectionViewCell performBatchUpdates animation time

There is a way to customize timing on animations done via performBatchUpdates?
I have this code
[self.stepCollectionView performBatchUpdates:^{
self.stepSelectedIndex = indexPath.row;
UICollectionViewCell *cell = [self.stepCollectionView cellForItemAtIndexPath:indexPath];
[UIView transitionWithView:cell
duration:0.5f
options: UIViewAnimationOptionLayoutSubviews | UIViewAnimationOptionBeginFromCurrentState
animations:^{
CGRect frame = cell.frame;
frame.size.height = 416;
cell.frame = frame;
}
completion:^(BOOL finished) {
}];
} completion:^(BOOL finished) {
}];
I would change the height of the UICollectionViewCell and at the same time reorganize the subviews of the UICollectionViewCell.
There is a way you can customise the duration and the Timing function for UICollectionView's batch update. Try the below code. And here is how it looks https://youtu.be/R0VdC4dliPI
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[CATransaction begin];
[CATransaction setAnimationDuration:0.3];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithControlPoints:0 :1.8 :0 :1]];
[self.menuCollectionView performBatchUpdates:^{
[self.menuCollectionView insertItemsAtIndexPaths:#[[NSIndexPath indexPathForItem:index inSection:0]]];
[animatableMenuItems insertObject:#"" atIndex:index];
} completion:^(BOOL finished) {
}];
[CATransaction commit];
[UIView commitAnimations];
Find the full source code for the example at https://github.com/DoddaSrinivasan/MultiRowUITabBar
Yes you can change the duration of this animation.
Change the layer.speed property of your UICollectionView.
Just wrap it up in a -[UIView animateWithDuration:animations:] block with your desired animation. It's probably not the correct way to do it, but it seems to work fine for me with iOS 8.
No, there is no way to customize the timing of the animation caused by performBatchUpdates. It looks like you are trying to animate just on Cell in particular in your collectionview. Why not just use + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations instead?

Resources