Skip to content
This repository has been archived by the owner on Oct 31, 2019. It is now read-only.

Minor changes in the library. #29

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 97 additions & 20 deletions DraggableCollectionView/Helpers/LSCollectionViewHelper.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ typedef NS_ENUM(NSInteger, _ScrollingDirection) {
@interface LSCollectionViewHelper ()
{
NSIndexPath *lastIndexPath;
UIImageView *mockCell;
UIView *mockCell;
CGPoint mockCenter;
CGPoint fingerTranslation;
CADisplayLink *timer;
Expand Down Expand Up @@ -209,6 +209,29 @@ - (NSIndexPath *)indexPathForItemClosestToPoint:(CGPoint)point
return indexPath;
}

- (NSIndexPath *)indexPathForItemAtPoint:(CGPoint)point
{
NSArray *layoutAttrsInRect;
NSIndexPath *indexPath;
NSIndexPath *toIndexPath = self.layoutHelper.toIndexPath;

// We need original positions of cells
self.layoutHelper.toIndexPath = nil;
layoutAttrsInRect = [self.collectionView.collectionViewLayout layoutAttributesForElementsInRect:self.collectionView.bounds];
self.layoutHelper.toIndexPath = toIndexPath;

// What cell are we closest to?
for (UICollectionViewLayoutAttributes *layoutAttr in layoutAttrsInRect)
{
if (CGRectContainsPoint(layoutAttr.frame, point))
{
indexPath = layoutAttr.indexPath;
}
}

return indexPath;
}

- (void)handleLongPressGesture:(UILongPressGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateChanged) {
Expand All @@ -218,7 +241,7 @@ - (void)handleLongPressGesture:(UILongPressGestureRecognizer *)sender
return;
}

NSIndexPath *indexPath = [self indexPathForItemClosestToPoint:[sender locationInView:self.collectionView]];
NSIndexPath *indexPath = [self indexPathForItemAtPoint:[sender locationInView:self.collectionView]];

switch (sender.state) {
case UIGestureRecognizerStateBegan: {
Expand All @@ -234,16 +257,42 @@ - (void)handleLongPressGesture:(UILongPressGestureRecognizer *)sender
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
cell.highlighted = NO;
[mockCell removeFromSuperview];
mockCell = [[UIImageView alloc] initWithFrame:cell.frame];
mockCell.image = [self imageFromCell:cell];
if([self.collectionView.dataSource respondsToSelector:@selector(collectionView:viewForDraggingAtIndexPath:)])
{
mockCell = [(id<UICollectionViewDataSource_Draggable>)self.collectionView.dataSource
collectionView:self.collectionView viewForDraggingAtIndexPath:indexPath];
mockCell.center = cell.center;
}
else
{
mockCell = [[UIImageView alloc] initWithFrame:cell.frame];
((UIImageView *)mockCell).image = [self imageFromCell:cell];
}
mockCenter = mockCell.center;
[self.collectionView addSubview:mockCell];
[UIView
animateWithDuration:0.3
animations:^{
mockCell.transform = CGAffineTransformMakeScale(1.1f, 1.1f);
}
completion:nil];
// Adding the mock cell to the root window so that if the collection view is not full screen,
// it is not clipped by the collection view when dragging.
[[self rootView] addSubview:mockCell];

mockCell.center = [self convertPointToRootView:mockCenter];

if([mockCell isKindOfClass:[UIImageView class]])
{
[UIView
animateWithDuration:0.3
animations:^{
mockCell.transform = CGAffineTransformMakeScale(1.1f, 1.1f);
}
completion:nil];
}
else
{
mockCell.transform = CGAffineTransformMakeScale((cell.bounds.size.width/mockCell.bounds.size.width),
(cell.bounds.size.height/mockCell.bounds.size.height));
[UIView animateWithDuration:0.3f
animations:^{
mockCell.transform = CGAffineTransformIdentity;
}];
}

// Start warping
lastIndexPath = indexPath;
Expand Down Expand Up @@ -274,8 +323,19 @@ - (void)handleLongPressGesture:(UILongPressGestureRecognizer *)sender
[UIView
animateWithDuration:0.3
animations:^{
mockCell.center = layoutAttributes.center;
mockCell.transform = CGAffineTransformMakeScale(1.f, 1.f);
mockCell.center = [self convertPointToRootView:layoutAttributes.center];

CGAffineTransform transform = CGAffineTransformIdentity;
if([mockCell isKindOfClass:[UIImageView class]])
{
transform = CGAffineTransformMakeScale(1.f, 1.f);
}
else
{
transform = CGAffineTransformMakeScale((layoutAttributes.frame.size.width/mockCell.bounds.size.width),
(layoutAttributes.frame.size.height/mockCell.bounds.size.height));
}
mockCell.transform = transform;
}
completion:^(BOOL finished) {
[mockCell removeFromSuperview];
Expand Down Expand Up @@ -317,17 +377,18 @@ - (void)handlePanGesture:(UIPanGestureRecognizer *)sender
if(sender.state == UIGestureRecognizerStateChanged) {
// Move mock to match finger
fingerTranslation = [sender translationInView:self.collectionView];
mockCell.center = _CGPointAdd(mockCenter, fingerTranslation);
CGPoint center = _CGPointAdd(mockCenter, fingerTranslation);
mockCell.center = [self convertPointToRootView:center];

// Scroll when necessary
if (canScroll) {
UICollectionViewFlowLayout *scrollLayout = (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
if([scrollLayout scrollDirection] == UICollectionViewScrollDirectionVertical) {
if (mockCell.center.y < (CGRectGetMinY(self.collectionView.bounds) + self.scrollingEdgeInsets.top)) {
if (center.y < (CGRectGetMinY(self.collectionView.bounds) + self.scrollingEdgeInsets.top)) {
[self setupScrollTimerInDirection:_ScrollingDirectionUp];
}
else {
if (mockCell.center.y > (CGRectGetMaxY(self.collectionView.bounds) - self.scrollingEdgeInsets.bottom)) {
if (center.y > (CGRectGetMaxY(self.collectionView.bounds) - self.scrollingEdgeInsets.bottom)) {
[self setupScrollTimerInDirection:_ScrollingDirectionDown];
}
else {
Expand All @@ -336,10 +397,10 @@ - (void)handlePanGesture:(UIPanGestureRecognizer *)sender
}
}
else {
if (mockCell.center.x < (CGRectGetMinX(self.collectionView.bounds) + self.scrollingEdgeInsets.left)) {
if (center.x < (CGRectGetMinX(self.collectionView.bounds) + self.scrollingEdgeInsets.left)) {
[self setupScrollTimerInDirection:_ScrollingDirectionLeft];
} else {
if (mockCell.center.x > (CGRectGetMaxX(self.collectionView.bounds) - self.scrollingEdgeInsets.right)) {
if (center.x > (CGRectGetMaxX(self.collectionView.bounds) - self.scrollingEdgeInsets.right)) {
[self setupScrollTimerInDirection:_ScrollingDirectionRight];
} else {
[self invalidatesScrollTimer];
Expand Down Expand Up @@ -404,12 +465,28 @@ - (void)handleScroll:(NSTimer *)timer {
}

mockCenter = _CGPointAdd(mockCenter, translation);
mockCell.center = _CGPointAdd(mockCenter, fingerTranslation);
CGPoint center = _CGPointAdd(mockCenter, fingerTranslation);
self.collectionView.contentOffset = _CGPointAdd(contentOffset, translation);

// Warp items while scrolling
NSIndexPath *indexPath = [self indexPathForItemClosestToPoint:mockCell.center];
NSIndexPath *indexPath = [self indexPathForItemClosestToPoint:center];
[self warpToIndexPath:indexPath];
}

- (CGPoint)convertPointToRootView:(CGPoint)point
{
return [self.collectionView convertPoint:point toView:[self rootView]];
}

- (CGPoint)convertPointFromRootView:(CGPoint)point
{
return [self.collectionView convertPoint:point fromView:[self rootView]];
}

- (UIView *)rootView
{
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
return window.subviews[0];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@

- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)toIndexPath;

// When dragging by default a cell copy (image) is created and tranform is applied.
// If you think the image looks blur when transform is applied, you can provide your own view by invoking this method.
// This method assumes that your view big enough so no transform is applied.
- (UIView *)collectionView:(UICollectionView *)collectionView viewForDraggingAtIndexPath:(NSIndexPath *)indexPath;

@end
13 changes: 13 additions & 0 deletions FlowLayoutDemo/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,17 @@ - (void)collectionView:(LSCollectionViewHelper *)collectionView moveItemAtIndexP
[data2 insertObject:index atIndex:toIndexPath.item];
}

- (UIView *)collectionView:(UICollectionView *)collectionView viewForDraggingAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *data = [sections objectAtIndex:indexPath.section];
NSString *text = [data objectAtIndex:indexPath.item];

UILabel *draggingView = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 200.0f, 200.0f)];
draggingView.backgroundColor = [UIColor lightGrayColor];
draggingView.font = [draggingView.font fontWithSize:draggingView.font.pointSize + 16.0f];
draggingView.textAlignment = NSTextAlignmentCenter;
draggingView.text = text;
return draggingView;
}

@end