Skip to content
This repository was archived by the owner on Jan 3, 2019. It is now read-only.

support one finger gesture and horizontal drag #20

Open
wants to merge 4 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
101 changes: 101 additions & 0 deletions Paper.xcodeproj/xcuserdata/Simay.xcuserdatad/xcschemes/Paper.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1AA0CC1418A07EBC008F50F6"
BuildableName = "Paper.app"
BlueprintName = "Paper"
ReferencedContainer = "container:Paper.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1AA0CC3518A07EBC008F50F6"
BuildableName = "PaperTests.xctest"
BlueprintName = "PaperTests"
ReferencedContainer = "container:Paper.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1AA0CC1418A07EBC008F50F6"
BuildableName = "Paper.app"
BlueprintName = "Paper"
ReferencedContainer = "container:Paper.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1AA0CC1418A07EBC008F50F6"
BuildableName = "Paper.app"
BlueprintName = "Paper"
ReferencedContainer = "container:Paper.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1AA0CC1418A07EBC008F50F6"
BuildableName = "Paper.app"
BlueprintName = "Paper"
ReferencedContainer = "container:Paper.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Paper.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>1AA0CC1418A07EBC008F50F6</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>1AA0CC3518A07EBC008F50F6</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
1 change: 1 addition & 0 deletions Paper/HACollectionViewLargeLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
#import "HAStickyHeaderLayout.h"

@interface HACollectionViewLargeLayout : HAStickyHeaderLayout
@property (nonatomic, strong) NSIndexPath *targetIndexPath;

@end
7 changes: 7 additions & 0 deletions Paper/HACollectionViewLargeLayout.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentO
}
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset {
if (_targetIndexPath) {
return CGPointMake(_targetIndexPath.row * (self.itemSize.width + self.minimumLineSpacing), 0);
}

return proposedContentOffset;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
Expand Down
113 changes: 113 additions & 0 deletions Paper/HATransitionController.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#import "HATransitionController.h"
#import "HATransitionLayout.h"
#import "HACollectionViewLargeLayout.h"


@interface HATransitionController ()

Expand All @@ -17,6 +19,11 @@ @interface HATransitionController ()
@property (nonatomic) CGPoint initialPinchPoint;
@property (nonatomic) CGFloat initialScale;

@property (nonatomic) NSIndexPath *cellIndexPath;
@property (nonatomic) BOOL isInitial;
@property (nonatomic) CGFloat targetY;


@end


Expand Down Expand Up @@ -78,6 +85,11 @@ - (void)startInteractiveTransition:(id <UIViewControllerContextTransitioning>)tr
UIView *containerView = [transitionContext containerView];
[containerView addSubview:[toCollectionViewController view]];

id toLayout = toCollectionViewController.collectionViewLayout;
if ([toLayout isKindOfClass:[HACollectionViewLargeLayout class]]) {
((HACollectionViewLargeLayout *)toLayout).targetIndexPath = _cellIndexPath;
}

self.transitionLayout = (HATransitionLayout *)[fromCollectionViewController.collectionView startInteractiveTransitionToCollectionViewLayout:toCollectionViewController.collectionViewLayout completion:^(BOOL didFinish, BOOL didComplete) {
[self.context completeTransition:didComplete];
self.transitionLayout = nil;
Expand Down Expand Up @@ -207,7 +219,108 @@ - (void)oneFingerGesture:(UIPanGestureRecognizer *)sender
CGPoint point = [sender locationInView:sender.view];
NSLog(@"point.x %f", point.x);
NSLog(@"point.y %f", point.y);

if (sender.state == UIGestureRecognizerStateEnded)
{
[self endInteractionWithSuccess:YES];
}
else if (sender.state == UIGestureRecognizerStateCancelled)
{
[self endInteractionWithSuccess:NO];
}
else if (sender.numberOfTouches == 1)
{
if (sender.state == UIGestureRecognizerStateBegan)
{
// start the pinch in our out
if (!self.hasActiveInteraction)
{
// 此处的记录可以使得向上拖拽变大时,用来显示最合适的cell,而不只是当前正在拖拽的cell
_cellIndexPath = [self.collectionView indexPathForItemAtPoint:point];
self.initialPinchPoint = point;
self.isInitial = NO;
self.hasActiveInteraction = YES; // the transition is in active motion
[self.delegate interactionBeganAtPoint:point];

}
}

if (self.hasActiveInteraction)
{
if (sender.state == UIGestureRecognizerStateChanged)
{
if (!self.transitionLayout) return;
if (!_isInitial) {
_isInitial = YES;
[self updateInitalDataWithPoint:point];
}

UIOffset offsetToUse = self.transitionLayout.offset;
CGFloat progress = ABS((point.y - _initialPinchPoint.y)/(_initialPinchPoint.y - _targetY));

if (self.navigationOperation == UINavigationControllerOperationPush) {
if (point.y < _targetY) {
progress = 1;
offsetToUse.vertical = point.y - _targetY;
}
else if (point.y > _initialPinchPoint.y) {
progress = 0;
offsetToUse.vertical = point.y - _initialPinchPoint.y;
}

}
else {
if (point.y > _targetY) {
progress = 1;
offsetToUse.vertical = point.y - _targetY;
}
else if (point.y < _initialPinchPoint.y) {
progress = 0;
offsetToUse.vertical = point.y - _initialPinchPoint.y;
}
}
CGPoint translation = [sender translationInView:sender.view];
offsetToUse.horizontal = translation.x;
[self updateWithProgress:progress andOffset:offsetToUse];
}
}
}

}
- (void)updateInitalDataWithPoint:(CGPoint)point {
id nextLayout = self.transitionLayout.nextLayout;
id currentLayout = self.transitionLayout.currentLayout;
if ([nextLayout isKindOfClass:[UICollectionViewFlowLayout class]] && [currentLayout isKindOfClass:[UICollectionViewFlowLayout class]]) {

CGFloat nextHeight = ((UICollectionViewFlowLayout *)nextLayout).itemSize.height;
CGFloat currentHeight = ((UICollectionViewFlowLayout *)currentLayout).itemSize.height;
CGFloat tallHeight = MAX(nextHeight, currentHeight);
CGFloat hRatio = (tallHeight - _initialPinchPoint.y) / currentHeight;
_targetY = tallHeight - nextHeight * hRatio;
}

}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {

if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
id layout = self.collectionView.collectionViewLayout;
if ([layout isKindOfClass:[UICollectionViewFlowLayout class]]) {
CGFloat height = ((UICollectionViewFlowLayout *)layout).itemSize.height;
CGPoint point = [gestureRecognizer locationInView:gestureRecognizer.view];
CGPoint translation = [(UIPanGestureRecognizer *)gestureRecognizer translationInView:gestureRecognizer.view];

//手指区域在collectionView内
//手指是上下滑动
if (point.y > self.collectionView.frame.size.height - height && ABS(translation.y) > ABS(translation.x)) {
return YES;
}
return NO;
}
}
return YES;
}



@end
2 changes: 1 addition & 1 deletion Paper/HATransitionLayout.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
if (currentAttribute.representedElementCategory != UICollectionElementCategorySupplementaryView) {
CGPoint currentCenter = currentAttribute.center;
CGPoint updatedCenter = CGPointMake(currentCenter.x, currentCenter.y + self.offset.vertical);
CGPoint updatedCenter = CGPointMake(currentCenter.x + self.offset.horizontal, currentCenter.y + self.offset.vertical);
currentAttribute.center = updatedCenter;
}

Expand Down