YapDatabaseViewConnection
@interface YapDatabaseViewConnection : YapDatabaseExtensionConnection
/**
* Returns the parent view instance.
*/
@property (nonatomic, strong, readonly) YapDatabaseView *parent;
/**
* Want to easily animate a tableView or collectionView when the view changes?
* Want an exact list of changes that happend to the view?
*
* You're in luck!
*
* Here's an overview of how it works:
*
* - (void)yapDatabaseModified:(NSNotification *)notification
* {
* // Jump to the most recent commit.
* // End & Re-Begin the long-lived transaction atomically.
* // Also grab all the notifications for all the commits that I jump.
* NSArray *notifications = [roDatabaseConnection beginLongLivedReadTransaction];
*
* // What changed in my tableView?
*
* NSArray *sectionChanges = nil;
* NSArray *rowChanges = nil;
*
* [[databaseConnection extension:@"sales"] getSectionChanges:§ionChanges
* rowChanges:&rowChanges
* forNotifications:notifications
* withMappings:mappings];
*
* if ([sectionChanges count] == 0 && [rowChanges count] == 0)
* {
* // There aren't any changes that affect our tableView!
* return;
* }
*
* // Familiar with NSFetchedResultsController?
* // Then this should look pretty familiar
*
* [self.tableView beginUpdates];
*
* for (YapDatabaseViewSectionChange *sectionChange in sectionChanges)
* {
* switch (sectionChange.type)
* {
* case YapDatabaseViewChangeDelete :
* {
* [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionChange.index]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* case YapDatabaseViewChangeInsert :
* {
* [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionChange.index]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* }
* }
* for (YapDatabaseViewRowChange *rowChange in rowChanges)
* {
* switch (rowChange.type)
* {
* case YapDatabaseViewChangeDelete :
* {
* [self.tableView deleteRowsAtIndexPaths:@[ rowChange.indexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* case YapDatabaseViewChangeInsert :
* {
* [self.tableView insertRowsAtIndexPaths:@[ rowChange.newIndexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* case YapDatabaseViewChangeMove :
* {
* [self.tableView deleteRowsAtIndexPaths:@[ rowChange.indexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* [self.tableView insertRowsAtIndexPaths:@[ rowChange.newIndexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* case YapDatabaseViewChangeUpdate :
* {
* [self.tableView reloadRowsAtIndexPaths:@[ rowChange.indexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* }
* }
*
* [self.tableView endUpdates];
* }
*/
- (void)getSectionChanges:(NSArray<YapDatabaseViewSectionChange *> * _Nonnull * _Nullable)sectionChangesPtr
rowChanges:(NSArray<YapDatabaseViewRowChange *> * _Nonnull * _Nullable)rowChangesPtr
forNotifications:(NSArray<NSNotification *> *)notifications
withMappings:(YapDatabaseViewMappings *)mappings
NS_REFINED_FOR_SWIFT;
/**
* A simple YES/NO query to see if the view changed at all, inclusive of all groups.
*/
- (BOOL)hasChangesForNotifications:(NSArray<NSNotification *> *)notifications;
/**
* A simple YES/NO query to see if a particular group within the view changed at all.
*/
- (BOOL)hasChangesForGroup:(NSString *)group inNotifications:(NSArray<NSNotification *> *)notifications;
/**
* A simple YES/NO query to see if any of the given groups within the view changed at all.
*/
- (BOOL)hasChangesForAnyGroups:(NSSet<NSString *> *)groups inNotifications:(NSArray<NSNotification *> *)notifications;
/**
* This method provides a rough estimate of the size of the change-set.
*
* There may be times when a huge change-set overloads the system.
* For example, imagine that 10,000 items were added to the view.
*
* Such a large change-set will likely take a bit longer to process via
* the getSectionChanges:rowChanges:forNotifications:withMappings: method.
* Not only that, but once you have the large arrays of sectionChanges & rowChanges,
* feeding them into the tableView / collectionView can potentially bog down the system
* while it attempts to calculate and perform the necessary animations.
*
* This method is very very fast, and simply returns a sum of the "raw" changes.
*
* By "raw" we mean that it includes each individual change to the view, without any processing.
* For example, if an item was deleted from one group, and inserted into another,
* then this represents 2 raw changes. During formal processing, these two raw operations
* would be consolidated into a single move operation.
* Also note that this method doesn't take a mappings parameter.
* So the sum of all raw changes may include things that would be filtered out during formal
* processing due to group restrictions or range restrictions of the mappings.
*
* However, this method is not intended to be precise.
* It is intended to be fast, and to provide a rough estimate that you might use to
* skip a potentially expensive operation.
*
* Example:
*
* - (void)yapDatabaseModified:(NSNotification *)notification
* {
* NSArray *notifications = [databaseConnection beginLongLivedReadTransaction];
*
* NSUInteger sizeEstimate = [[databaseConnection ext:@"myView"] numberOfRawChangesForNotifications:notifications];
* if (sizeEstimate > 150)
* {
* // Looks like a huge changeset, so let's just reload the tableView (faster)
*
* // We're not going to call getSectionChanges:rowChanges:forNotifications:withMappings:.
* // We don't need to know the sectionChanges & rowChanges.
* // But we do need to move our mappings to the latest commit,
* // so that it matches our databaseConnections.
* // We can take a shortcut to do this, and simply tell it to "refresh" using our databaseConnection.
* [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction){
* [mappings updateWithTransaction:transaction];
* }];
*
* // And then we can reload our tableView, and return
* [tableView reloadData];
* return;
* }
*
* // Normal code stuff
*
* NSArray *sectionChanges = nil;
* NSArray *rowChanges = nil;
* [[databaseConnection ext:@"myView"] getSectionChanges:§ionChanges
* rowChanges:&rowChanges
* forNotifications:notifications
* withMappings:mappings];
*
* // Normal animation code goes here....
* }
*/
- (NSUInteger)numberOfRawChangesForNotifications:(NSArray<NSNotification *> *)notifications;
@end
Undocumented
-
Returns the parent view instance.
Declaration
Objective-C
@property (readonly, strong, nonatomic) YapDatabaseView *_Nonnull parent;
Swift
var parent: YapDatabaseView { get }
-
Want to easily animate a tableView or collectionView when the view changes? Want an exact list of changes that happend to the view?
You’re in luck!
Here’s an overview of how it works:
(void)yapDatabaseModified:(NSNotification *)notification { // Jump to the most recent commit. // End & Re-Begin the long-lived transaction atomically. // Also grab all the notifications for all the commits that I jump. NSArray *notifications = [roDatabaseConnection beginLongLivedReadTransaction];
// What changed in my tableView?
NSArray *sectionChanges = nil; NSArray *rowChanges = nil;
[[databaseConnection extension:@
sales
] getSectionChanges:§ionChanges rowChanges:&rowChanges forNotifications:notifications withMappings:mappings];if ([sectionChanges count] == 0 && [rowChanges count] == 0) { // There aren’t any changes that affect our tableView! return; }
// Familiar with NSFetchedResultsController? // Then this should look pretty familiar
[self.tableView beginUpdates];
for (YapDatabaseViewSectionChange *sectionChange in sectionChanges) { switch (sectionChange.type) { case YapDatabaseViewChangeDelete : { [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionChange.index] withRowAnimation:UITableViewRowAnimationAutomatic]; break; } case YapDatabaseViewChangeInsert : { [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionChange.index] withRowAnimation:UITableViewRowAnimationAutomatic]; break; } } } for (YapDatabaseViewRowChange *rowChange in rowChanges) { switch (rowChange.type) { case YapDatabaseViewChangeDelete : { [self.tableView deleteRowsAtIndexPaths:@[ rowChange.indexPath ] withRowAnimation:UITableViewRowAnimationAutomatic]; break; } case YapDatabaseViewChangeInsert : { [self.tableView insertRowsAtIndexPaths:@[ rowChange.newIndexPath ] withRowAnimation:UITableViewRowAnimationAutomatic]; break; } case YapDatabaseViewChangeMove : { [self.tableView deleteRowsAtIndexPaths:@[ rowChange.indexPath ] withRowAnimation:UITableViewRowAnimationAutomatic]; [self.tableView insertRowsAtIndexPaths:@[ rowChange.newIndexPath ] withRowAnimation:UITableViewRowAnimationAutomatic]; break; } case YapDatabaseViewChangeUpdate : { [self.tableView reloadRowsAtIndexPaths:@[ rowChange.indexPath ] withRowAnimation:UITableViewRowAnimationAutomatic]; break; } } }
[self.tableView endUpdates]; }
Declaration
Objective-C
- (void)getSectionChanges: (NSArray<YapDatabaseViewSectionChange *> *_Nonnull *_Nullable) sectionChangesPtr rowChanges: (NSArray<YapDatabaseViewRowChange *> *_Nonnull *_Nullable) rowChangesPtr forNotifications:(nonnull NSArray<NSNotification *> *)notifications withMappings:(nonnull YapDatabaseViewMappings *)mappings;
Swift
func __getSectionChanges(_ sectionChangesPtr: AutoreleasingUnsafeMutablePointer<NSArray>?, rowChanges rowChangesPtr: AutoreleasingUnsafeMutablePointer<NSArray>?, for notifications: [Notification], with mappings: YapDatabaseViewMappings)
-
A simple YES/NO query to see if the view changed at all, inclusive of all groups.
Declaration
Objective-C
- (BOOL)hasChangesForNotifications: (nonnull NSArray<NSNotification *> *)notifications;
Swift
func hasChanges(for notifications: [Notification]) -> Bool
-
A simple YES/NO query to see if a particular group within the view changed at all.
Declaration
Objective-C
- (BOOL)hasChangesForGroup:(nonnull NSString *)group inNotifications:(nonnull NSArray<NSNotification *> *)notifications;
Swift
func hasChanges(forGroup group: String, in notifications: [Notification]) -> Bool
-
A simple YES/NO query to see if any of the given groups within the view changed at all.
Declaration
Objective-C
- (BOOL)hasChangesForAnyGroups:(nonnull NSSet<NSString *> *)groups inNotifications: (nonnull NSArray<NSNotification *> *)notifications;
Swift
func hasChanges(forAnyGroups groups: Set<String>, in notifications: [Notification]) -> Bool
-
This method provides a rough estimate of the size of the change-set.
There may be times when a huge change-set overloads the system. For example, imagine that 10,000 items were added to the view.
Such a large change-set will likely take a bit longer to process via the getSectionChanges:rowChanges:forNotifications:withMappings: method. Not only that, but once you have the large arrays of sectionChanges & rowChanges, feeding them into the tableView / collectionView can potentially bog down the system while it attempts to calculate and perform the necessary animations.
This method is very very fast, and simply returns a sum of the
raw
changes.By
raw
we mean that it includes each individual change to the view, without any processing. For example, if an item was deleted from one group, and inserted into another, then this represents 2 raw changes. During formal processing, these two raw operations would be consolidated into a single move operation. Also note that this method doesn’t take a mappings parameter. So the sum of all raw changes may include things that would be filtered out during formal processing due to group restrictions or range restrictions of the mappings.However, this method is not intended to be precise. It is intended to be fast, and to provide a rough estimate that you might use to skip a potentially expensive operation.
Example:
(void)yapDatabaseModified:(NSNotification *)notification { NSArray *notifications = [databaseConnection beginLongLivedReadTransaction];
NSUInteger sizeEstimate = [[databaseConnection ext:@
myView
] numberOfRawChangesForNotifications:notifications]; if (sizeEstimate > 150) { // Looks like a huge changeset, so let’s just reload the tableView (faster)// We're not going to call getSectionChanges:rowChanges:forNotifications:withMappings:. // We don't need to know the sectionChanges & rowChanges. // But we do need to move our mappings to the latest commit, // so that it matches our databaseConnections. // We can take a shortcut to do this, and simply tell it to "refresh" using our databaseConnection. [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction){ [mappings updateWithTransaction:transaction]; }]; // And then we can reload our tableView, and return [tableView reloadData]; return;
}
// Normal code stuff
NSArray *sectionChanges = nil; NSArray *rowChanges = nil; [[databaseConnection ext:@
myView
] getSectionChanges:§ionChanges rowChanges:&rowChanges forNotifications:notifications withMappings:mappings];// Normal animation code goes here…. }
Declaration
Objective-C
- (NSUInteger)numberOfRawChangesForNotifications: (nonnull NSArray<NSNotification *> *)notifications;
Swift
func numberOfRawChanges(for notifications: [Notification]) -> UInt