performBatchUpdates on collectionview & allow user interaction - ios

I'm trying to let the user have some control over the screen while updates are being performed on a collection view.
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadData];
} completion:^(BOOL finished) {}];
I've tried wrapping the whole thing in an animation block and UIViewAnimationOptionAllowUserInteraction but no dice. Any thoughts how this might be done?
Thanks!

Related

Perform UICollectionView reloadData without animation

I have UICollectionView cells with a rounded button inside, when I perform reloadData every rounded button goes from the left to the right. To avoid it, I'm using:
[UIView performWithoutAnimation:^{
[self.collectionView reloadData];
}];
but it doesn't seem to work anymore on iOS 14, can someone help me?
This is the correct way to do it:
[UIView performWithoutAnimation:^{
[self.collectionView reloadData];
[self.collectionView layoutIfNeeded];
}];

Slowing down row insertion animation in UITableView

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..

Disable UICollectionView animation on reloadData

For some reason, my UICollectionView animates the transition inside the visible cell when calling reloadData.
From what I understood it shouldn't do that, and that's what I am trying to do.
Why would the collection view animate on reload data? And how could I stop it?
I will be eventually using [UIView setAnimationsEnabled:YES/NO], but I would be hoping to fix it without too much extra code.
[UIView performWithoutAnimation:^{
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
}];

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?

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