Skip to content
This repository has been archived by the owner on Jul 1, 2020. It is now read-only.

Commit

Permalink
Documentation for the entire reordering component
Browse files Browse the repository at this point in the history
  • Loading branch information
Jordan Morgan committed Jan 4, 2017
1 parent 215e994 commit ed6910a
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 5 deletions.
4 changes: 1 addition & 3 deletions BFRTableReorder/BFRTableReorder/ViewController.m
Expand Up @@ -24,12 +24,10 @@ - (void)viewDidLoad {
[super viewDidLoad];
self.useMultipleSections = YES;
self.items = [[NSMutableArray alloc] initWithArray:@[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10"]];

NSMutableArray *section1 = [[NSMutableArray alloc] initWithObjects:@"1", @"2", nil];
NSMutableArray *section2 = [[NSMutableArray alloc] initWithObjects:@"3", @"4", nil];
NSMutableArray *section3 = [[NSMutableArray alloc] initWithObjects:@"5", @"6", nil];
self.multipleItems = [[NSMutableArray alloc] initWithArray:@[section1, section2, section3]];

self.tableNode = [[ASTableNode alloc] initWithStyle:self.useMultipleSections ? UITableViewStyleGrouped : UITableViewStylePlain];
self.tableNode.delegate = self;
self.tableNode.dataSource = self;
Expand Down Expand Up @@ -86,7 +84,7 @@ - (NSInteger)numberOfSectionsInTableNode:(ASTableNode *)tableNode {
}

- (ASCellNodeBlock)tableNode:(ASTableNode *)tableNode nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([tableNode.reorder shouldShowSpacerCellForIndexPath:indexPath]) {
if ([tableNode.reorder shouldShowSpacerNodeForIndexPath:indexPath]) {
ASCellNode *(^ASCellNodeBlock)() = ^ASCellNode *() {
ASCellNode *cell = [ASCellNode new];
cell.style.preferredSize = CGSizeMake(0, tableNode.reorder.sourceHeight);
Expand Down
4 changes: 4 additions & 0 deletions BFRTableReorder/ReorderSource/ASTableNode+BFRReorder.h
Expand Up @@ -11,6 +11,10 @@

@interface ASTableNode (BFRReorder)


/**
The primary controller for the reordering operations.
*/
@property (nonatomic, weak, nullable) BFRReorderController *reorder;

@end
19 changes: 19 additions & 0 deletions BFRTableReorder/ReorderSource/BFRIndexPathSnapDistance.h
Expand Up @@ -9,11 +9,30 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

/**
A small class that holds information to help computes distances from the snap shot node to other cell nodes to know where animations, reordering and other opertaions should occur at.
*/
@interface BFRIndexPathSnapDistance : NSObject


/**
The given @c NSIndexPath that is being used to reorder to or away from.
*/
@property (strong, nonatomic) NSIndexPath *indexPath;

/**
Holds the distance a snap shot node is being moved away from, or to, another cell node.
*/
@property (nonatomic) CGFloat distance;


/**
Returns an instance of a @c BFRIndexPathSnapDistance to aid with reordering away and from index paths.
@param path The current @c NSIndexPath to be checked against.
@param distance The current distance to the next index path that the snap shot node is going to, or moving away from.
@return An instance of @c BFRIndexPathSnapDisance.
*/
- (instancetype)initWithPath:(NSIndexPath *)path distance:(CGFloat)distance;

@end
103 changes: 102 additions & 1 deletion BFRTableReorder/ReorderSource/BFRReorderController.h
Expand Up @@ -10,36 +10,137 @@
#import <UIKit/UIKit.h>
#import <AsyncDisplayKit/AsyncDisplayKit.h>


/**
Reordering delegate meant to be used with @c ASTableNode instances.
*/
@protocol BFRTableViewReorderDelegate <NSObject, ASTableDelegate>

@required

/**
The primary function to reorder items in @c ASTableNode instances. Here you'll define what should happen to the datasource when a reorder operation occurs.
@param tableNode The tableNode instance reordering is occurring on.
@param fromIndexPath The @c NSIndexPath where the node is moving from.
@param toIndexPath the @c NSIndexPath where the node is moving to.
*/
- (void)tableNode:(ASTableNode *)tableNode redorderRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath;

@optional


/**
If NO is returned here, reordering logic does not occur at the given @c NSIndexPath.
@param tableNode The tableNode instance reordering is occurring on.
@param indexPath The proposed @c NSIndexPath to apply reordering logic against.
@return A BOOL value indicating whether or not reordering logic should occur at the given @c NSIndexPath.
*/
- (BOOL)tableNode:(ASTableNode *)tableNode canReorderRowAtIndexPath:(NSIndexPath *)indexPath;


/**
Invoked right before reordering logic occurs.
@param tableNode The tableNode instance reordering is occurring on.
*/
- (void)tableNodeWillBeginReordering:(ASTableNode *)tableNode;


/**
Invoked right after reordering logic begins.
@param tableNode The tableNode instance reordering is occurring on.
*/
- (void)tableNodeDidBeginReordering:(ASTableNode *)tableNode;


/**
Invoked right after reordering logic finishes.
@param tableNode The tableNode instance reordering is occurring on.
*/
- (void)tableNodeDidFinishReordering:(ASTableNode *)tableNode;

@optional


@end


/**
This class houses the logic for reordering @c ASCellNode instances. It's meant to be used as a category for any @c ASTableNode instance. It works by shuffling around data source items via it's delegate property, @cBFRTableViewReorderDelegate, and by creating a snapshot node that is dragged up and down that mimics the look of the node that was long pressed on. The snapshot node is configurable via the public properties found in this class. Note that you should invoke @c -(BOOL)shouldShowSpacerNodeForIndexPath:indexPath within @c -(ASCellNodeBlock)tableNode:tableNodenodeBlockForRowAtIndexPath: to see whether or not you should supply a spacer node at the given @c NSIndexPath.
*/
@interface BFRReorderController : NSObject


/**
The primary delegate of an @c ASTableNode instance that controls reordering.
*/
@property (nonatomic, weak) id <BFRTableViewReorderDelegate> delegate;

/**
The duration that should elapse before reordering begins.
*/
@property (nonatomic) NSTimeInterval longPressDuration;

/**
The duration of all the animations that occur during reordering, such as the snapshot node being created and table reorder operations.
*/
@property (nonatomic) NSTimeInterval animationDuration;

/**
The opacity that the snapshot node will have during reordering.
*/
@property (nonatomic) CGFloat cellOpacity;

/**
The scale that the snapshot node will have during reordering.
*/
@property (nonatomic) CGFloat cellScale;

/**
The color that the snapshot node will have during reordering, if a shadow is used.
*/
@property (strong, nonatomic) UIColor *shadowColor;

/**
The shadow opacity that the snapshot node will have during reodering, if a shadow is used.
*/
@property (nonatomic) CGFloat shadowOpacity;

/**
The radius of the shadow that the snapshot node will have during reordering, if a shadow is used.
*/
@property (nonatomic) CGFloat shadowRadius;

/**
The offset of the shadow that the snapshot node will have during reordering, if a shadow is used.
*/
@property (nonatomic) CGSize shadowOffset;

/**
When reordering occurs, this will represent the height of the node that the snapshot node is about to mimic. This can be set by the API consumer as well, should various edge cases present themselves. Typically, you should set your spacer node's height to this value.
*/
@property (nonatomic) CGFloat sourceHeight;

- (BOOL)shouldShowSpacerCellForIndexPath:(NSIndexPath *)indexPath;

/**
Returns YES if a spacer node should be displayed by the consumer in it's node block for the @c NSIndexPath. This helps with the presentation of the node, which makes it appear as if it is fading away when the snapshot node passes over it.
@param indexPath The @c NSIndexPath where the check for a spacer node will occur.
@return Returns YES if the consumer should supply a dummy space node for inside of their node block at the given @c NSIndexPath.
*/
- (BOOL)shouldShowSpacerNodeForIndexPath:(NSIndexPath *)indexPath;


/**
Initializes a fully configurable reodering instance.
@param tableNode The tableNode instance to use reordering with.
@return A reordering controller instance. More setup can occur after initialization via its public properties.
*/
- (instancetype)initWithTableView:(ASTableNode *)tableNode;

@end
2 changes: 1 addition & 1 deletion BFRTableReorder/ReorderSource/BFRReorderController.m
Expand Up @@ -130,7 +130,7 @@ - (void)endReorder {
}

#pragma mark - Spacer Cell
- (BOOL)shouldShowSpacerCellForIndexPath:(NSIndexPath *)indexPath {
- (BOOL)shouldShowSpacerNodeForIndexPath:(NSIndexPath *)indexPath {
if (self.reorderState.state == Reordering && [self.reorderState.destinationRow isEqual:indexPath]) {
return YES;
}
Expand Down
30 changes: 30 additions & 0 deletions BFRTableReorder/ReorderSource/BFRReorderState.h
Expand Up @@ -9,17 +9,47 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>


/**
Represents the state of the current reorder operation.
- Ready: Means that the @c ASTableNode instance is ready to reorder.
- Reordering: Means that the @c ASTableNode instance is currently reordering.
*/
typedef NS_ENUM(NSInteger, State) {
Ready,
Reordering
};


/**
A simple class that controls state for the current, or proposed, reordering operation that happens via a @c BFRReorderController instance.
*/
@interface BFRReorderState : NSObject

/**
The current state of the reorder operations, which is either ready or in progress.
*/
@property (nonatomic) State state;

/**
Holds the row that is about to be reordered, which in turn should have a spacer node put in its place.
*/
@property (strong, nonatomic) NSIndexPath *snapshotRow;

/**
The row where reordering started at.
*/
@property (strong, nonatomic) NSIndexPath *sourceRow;

/**
The proposed row where the @c sourceRow is attempting to be moved to.
*/
@property (strong, nonatomic) NSIndexPath *destinationRow;

/**
An offset that's applied to the snap shot node. This will be set by an @c BFRReorderController instance.
*/
@property (nonatomic) CGFloat snapshotOffset;

@end

0 comments on commit ed6910a

Please sign in to comment.