Slowing down row insertion animation in UITableView - ios

Is there a way to slow down the row insertion/deletion animation ?
In my particular case, I'm expanding/colapsing a cell by adding/removing rows below my cell and I'd like to slow the animation a little bit.

I'm using the below tricks to animate insert/delete the table view cells in my project, which works fine.
you can try this out. Happy coding!!!
// Here you can change the animation duration based on ur needs
NSTimeInterval animationDuration = 2.0f;
[UIView animateWithDuration:animationDuration animations:^{
// Disable the user interaction to the view if needed, otherwise user may interact with table view.
//view.userInteractionEnabled = NO;
[tableview beginUpdates];
// insert object to table view data source
//[yourArray insertObject:#"Some object" atIndex:some indexpath];
// Perform insert animation
//[tableview insertRowsAtIndexPaths:[NSArray arrayWithObject:someindexpath] withRowAnimation:UITableViewRowAnimationRight];
[tableview endUpdates];
} completion:^(BOOL finished) {
NSLog(#"Animation done");
// Enable the user interaaction now
//view.userInteractionEnabled = YES;
}];

Try to add/remove rows as following :
[_tableView beginUpdates];
// your add/remove func
[_tableView endUpdates];
Do UI changes for Tableview like above to reduce slow behaviour.
Hope it helps..

Related

Animation when remove UICollectionViewCell

I have collection view, and have logic to delete cells from it. However, when cell is removed, next cell is appeared instantly on deleted cell place. Is there a way to add animation for deletion, for example, for 0.5 sec change opaque of cell, or something similar? There is a method i use for delete cell:
-(void)aMethod:(UIButton*)sender{
[self.viewModel deleteAt:[sender tag]];
[self.myCollectionView reloadData];
}
You have to use:
[UIView performWithoutAnimation:^{
[self.myCollectionView reloadData];
}];

Removing object on a tableView animation

I have a UITableView and when the user swipes on one of the cells he can delete the cell (delete the object from the array).
But for example, when the user swipes on a cell in the middle of the table the animation is made on the last cell (the one on the bottom) like in this video:
https://vid.me/D0pi
Here is the code for this deletion:
//Removing cell from "AroundersTableView"(UITableView) with UITableViewRowAnimationLeft
[self.AroundersTableView beginUpdates];
[self.Arounders removeObjectAtIndex:cellRowToDelete];
[self.AroundersTableView deleteRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:cellRowToDelete inSection:0]] withRowAnimation:UITableViewRowAnimationLeft];
[self.AroundersTableView endUpdates];
//Saving Arounders
[self saveArounders];
//Creating "newTableFrame"(CGRect) and setting it to current "AroundersTableView"'s frame will one less cell
CGRect newTableFrame=self.AroundersTableView.frame;
newTableFrame.origin.y+=44;
//Animating "AroundersTableView" to the new frame
[UIView animateWithDuration:0.5 animations:^{
self.AroundersTableView.frame=newTableFrame;
}];
//ReConfiguring "AroundersTableView"(UITableView) height
[self performSelector:#selector(configureTableViewsHeight) withObject:nil afterDelay:0.5];
//Reloading "AroundersTableView"(UITableView) data
[self.AroundersTableView reloadData];
Note: configureTableViewsHeight is just a method the makes the tableView height to be the cell.height*Arounders.count (cells height * number of cells).
I have no idea why it's happening.
Why is it? How can I make the animation on the correct cell (the all the cells above it are going down and hiding the red part)?
Thank you!

Stop animation in UICollectionView cell

I have a timer that fires every second to refresh data on a UICollectionView cell, sometimes (especially when I rotate the device), the cell starts to blink every second. I want to stop this blink animation. However, I have another animation going on inside the collection view cell, so I don't want to disable all animations on it as this code does:
[UIView setAnimationsEnabled:NO];
[collectionView performBatchUpdates:^{
[collectionView reloadItemsAtIndexPaths:indexPaths];
} completion:^(BOOL finished) {
[UIView setAnimationsEnabled:YES];
}];
If you don't want animation on reloading collection view, why don't you just call
[collectionView reloadData];
It only reloads all visible cells.
For the animation inside of the collection view cell, why not code more in the cell object?

UITableView animation glitch when deleting and inserting cells with varying heights

I am having a problem with the animation that UITableView provides when deleting and inserting a cell at the same time.
I have a list of cells lets call them questions. When one question is tapped it should add a cell beneath itself to display the answer to that question. If another answer is already being displayed that answer should be removed from the table.
The issue arises when the cell being inserted is very tall. If it is so tall that it's eventual bounds encroach into the space that the cell to be deleted takes up then during the animation we see the through the answer cell that we are deleting to see the cell that is being added
(see link to video of problem)
the is what my code looks like to move around the cells in the table view
[tableView beginUpdates];
if (deleteIndex) {
[tableView deleteRowsAtIndexPaths:#[deleteIndex] withRowAnimation:UITableViewRowAnimationTop];
}
if (addIndex) {
[tableView insertRowsAtIndexPaths:#[addIndex] withRowAnimation:UITableViewRowAnimationTop];
}
[tableView endUpdates];
I have tried
[tableView beginUpdates];
if (deleteIndex) {
[tableView deleteRowsAtIndexPaths:#[deleteIndex] withRowAnimation:UITableViewRowAnimationTop];
}
[tableView endUpdates];
//do stuff to update data source
[tableView beginUpdates];
if (addIndex) {
[tableView insertRowsAtIndexPaths:#[addIndex] withRowAnimation:UITableViewRowAnimationTop];
}
[tableView endUpdates];
But because there's no callback confirming that the table view did complete the first set update before starting the second block pretty much the same problem occurs. I know I could use perform selector with delay, but this seems like a bandaid.
Second I tried to encompass the animation in a block like this
[UIView animateWithDuration:0.0 animations:^{
[tableView beginUpdates];
if (deleteIndex) {
[tableView deleteRowsAtIndexPaths:#[deleteIndex] withRowAnimation:UITableViewRowAnimationTop];
}
[tableView endUpdates];
//do stuff to update data source
} completion:^(BOOL finished) {
[tableView beginUpdates];
if (addIndex) {
[tableView insertRowsAtIndexPaths:#[addIndex] withRowAnimation:UITableViewRowAnimationTop];
}
[tableView endUpdates];
}];
Again, because the completion block is fired after we call endUpdates not after the updates actually complete this does not resolve the use.
I also went into storyboard to be sure that clip subviews to bounds is selected for the cells. Again, this does not resolve the issue because we are not seeing a subview of the cell expand beyond it's expected height.
Looking closer at the animation by slowing it down it looks like apple inserts the cell to be added under the cells that won't be changed in the table and then moves the cells that will remain into their new positions. As a result the cell that was deleted becomes a transparent window where we see what they are actually doing under the hood.
The right approach would be to first remove the old answer and then after the animation is over add the new answer. There is a UITableViewDelegate method that is triggered after the cell animation is complete.
tableView:didEndDisplayingCell:forRowAtIndexPath:
Inserting the new answer row within this delegate method will result in the correct animation.
There are a few details to keep in mind- You'll need some logic to ensure that the correct cell height is returned and that the correct number of expected rows in the section is returned. Those data source methods are called after we remove our old answer in and again when we add the new one when we call
endUpdates
on the table view
Using anything other than UITableViewRowAnimationTop results in some strange animation behavior. This is because the content view of the cell is not what is being animated.
i solve same problem in my project by hide control like:
in ~cell.m have
(void)setSelected:(BOOL)selected animated:(BOOL)animated;
{
if(selected == NO)
{
self.selectedView.hidden = YES;
self.descriptionLabel.hidden = YES;
}
else
{
self.selectedView.hidden = NO;
self.descriptionLabel.hidden = NO;
}
}
may it still helpful

UICollectionView animate data change

In my Project I use UICollectionView to display a grid of icons.
The user is able to change the ordering by clicking a segmented control which calling a fetch from core data with different NSSortDescriptor.
The amount of data is always the same, just ending up in different sections / rows:
- (IBAction)sortSegmentedControlChanged:(id)sender {
_fetchedResultsController = nil;
_fetchedResultsController = [self newFetchResultsControllerForSort];
NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
[self.collectionView reloadData];
}
The problem is that reloadData doesn't animate the change, UICollectionView just pops with the new data.
Should I keep track in which indexPath a cell was before and after change, and use [self.collectionView moveItemAtIndexPath: toIndexPath:] to perform the animation for the change or there is a better method ?
I didn't get much into subclassing collectionViews so any help will be great...
Thanks,
Bill.
Wrapping -reloadData in -performBatchUpdates: does not seem to cause a one-section collection view to animate.
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadData];
} completion:nil];
However, this code works:
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];
reloadData doesn't animate, nor does it reliabably do so when put in a UIView animation block. It wants to be in a UICollecitonView performBatchUpdates block, so try something more like:
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {
// do something on completion
}];
This is what I did to animate reload of ALL SECTIONS:
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];
Swift 3
let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
let indexSet = IndexSet(integersIn: range)
collectionView.reloadSections(indexSet)
For Swift users, if your collectionview only has one section:
self.collectionView.performBatchUpdates({
let indexSet = IndexSet(integersIn: 0...0)
self.collectionView.reloadSections(indexSet)
}, completion: nil)
As seen on https://stackoverflow.com/a/42001389/4455570
Reloading the whole collection view inside a performBatchUpdates:completion: block does a glitchy animation for me on iOS 9 simulator. If you have a specific UICollectionViewCell you want do delete, or if you have it's index path, you could call deleteItemsAtIndexPaths: in that block. By using deleteItemsAtIndexPaths:, it does a smooth and nice animation.
UICollectionViewCell* cellToDelete = /* ... */;
NSIndexPath* indexPathToDelete = /* ... */;
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:#[[self.collectionView indexPathForCell:cell]]];
// or...
[self.collectionView deleteItemsAtIndexPaths:#[indexPath]];
} completion:nil];
The help text says:
Call this method to reload all of the items in the collection view.
This causes the collection view to discard any currently visible items
and redisplay them. For efficiency, the collection view only displays
those cells and supplementary views that are visible. If the
collection data shrinks as a result of the reload, the collection view
adjusts its scrolling offsets accordingly. You should not call this
method in the middle of animation blocks where items are being
inserted or deleted. Insertions and deletions automatically cause the
table’s data to be updated appropriately.
I think the key part is "causes the collection view to discard any currently visible items". How is it going to animate the movement of items it has discarded?

Resources