@@ -91,15 +91,18 @@ @interface CCMoveToX : CCActionInterval
91
91
{
92
92
float _endPosition;
93
93
float _startPos;
94
+ void (^block)(void );
94
95
}
95
96
@end
96
97
97
98
@implementation CCMoveToX
98
99
99
- -(id ) initWithDuration : (CCTime) t positionX : (float ) p
100
+ -(id ) initWithDuration : (CCTime) t positionX : (float ) p callback : ( void (^)( void )) callback
100
101
{
101
- if ( (self=[super initWithDuration: t]) )
102
+ if ( (self=[super initWithDuration: t]) ) {
102
103
_endPosition = p;
104
+ block = callback;
105
+ }
103
106
return self;
104
107
}
105
108
@@ -119,6 +122,7 @@ -(void) update: (CCTime) t
119
122
float y = node.position .y ;
120
123
121
124
node.position = ccp (x,y);
125
+ block ();
122
126
}
123
127
@end
124
128
@@ -127,15 +131,18 @@ @interface CCMoveToY : CCActionInterval
127
131
{
128
132
float _endPosition;
129
133
float _startPos;
134
+ void (^block)(void );
130
135
}
131
136
@end
132
137
133
138
@implementation CCMoveToY
134
139
135
- -(id ) initWithDuration : (CCTime) t positionY : (float ) p
140
+ -(id ) initWithDuration : (CCTime) t positionY : (float ) p callback : ( void (^)( void )) callback
136
141
{
137
- if ( (self=[super initWithDuration: t]) )
142
+ if ( (self=[super initWithDuration: t]) ) {
138
143
_endPosition = p;
144
+ block = [callback copy ];
145
+ }
139
146
return self;
140
147
}
141
148
@@ -155,14 +162,21 @@ -(void) update: (CCTime) t
155
162
float x = node.position .x ;
156
163
157
164
node.position = ccp (x,y);
165
+ block ();
158
166
}
159
167
@end
160
168
161
169
162
170
#pragma mark -
163
171
#pragma mark CCScrollView
164
172
165
- @implementation CCScrollView
173
+ @implementation CCScrollView {
174
+ BOOL _decelerating;
175
+
176
+ #ifdef __CC_PLATFORM_MAC
177
+ CGPoint _lastPosition;
178
+ #endif
179
+ }
166
180
167
181
#pragma mark Initializers
168
182
@@ -335,31 +349,13 @@ - (void) setScrollPosition:(CGPoint)newPos
335
349
336
350
- (void ) setScrollPosition : (CGPoint)newPos animated : (BOOL )animated
337
351
{
352
+ // Check bounds
353
+ newPos.x = MAX (MIN (newPos.x , self.maxScrollX ), self.minScrollX );
354
+ newPos.y = MAX (MIN (newPos.y , self.maxScrollY ), self.minScrollY );
355
+
338
356
BOOL xMoved = (newPos.x != self.scrollPosition .x );
339
357
BOOL yMoved = (newPos.y != self.scrollPosition .y );
340
-
341
- // Check bounds
342
- if (newPos.x > self.maxScrollX )
343
- {
344
- newPos.x = self.maxScrollX ;
345
- xMoved = YES ;
346
- }
347
- if (newPos.x < self.minScrollX )
348
- {
349
- newPos.x = self.minScrollX ;
350
- xMoved = YES ;
351
- }
352
- if (newPos.y > self.maxScrollY )
353
- {
354
- newPos.y = self.maxScrollY ;
355
- yMoved = YES ;
356
- }
357
- if (newPos.y < self.minScrollY )
358
- {
359
- newPos.y = self.minScrollY ;
360
- yMoved = YES ;
361
- }
362
-
358
+
363
359
if (animated)
364
360
{
365
361
CGPoint oldPos = self.scrollPosition ;
@@ -375,7 +371,9 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
375
371
_animatingX = YES ;
376
372
377
373
// Create animation action
378
- CCActionInterval* action = [CCActionEaseOut actionWithAction: [[CCMoveToX alloc ] initWithDuration: duration positionX: -newPos.x] rate: 2 ];
374
+ CCActionInterval* action = [CCActionEaseOut actionWithAction: [[CCMoveToX alloc ] initWithDuration: duration positionX: -newPos.x callback: ^{
375
+ [self scrollViewDidScroll ];
376
+ }] rate: 2 ];
379
377
CCActionCallFunc* callFunc = [CCActionCallFunc actionWithTarget: self selector: @selector (xAnimationDone )];
380
378
action = [CCActionSequence actions: action, callFunc, nil ];
381
379
action.tag = kCCScrollViewActionXTag ;
@@ -389,7 +387,9 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
389
387
_animatingY = YES ;
390
388
391
389
// Create animation action
392
- CCActionInterval* action = [CCActionEaseOut actionWithAction: [[CCMoveToY alloc ] initWithDuration: duration positionY: -newPos.y] rate: 2 ];
390
+ CCActionInterval* action = [CCActionEaseOut actionWithAction: [[CCMoveToY alloc ] initWithDuration: duration positionY: -newPos.y callback: ^{
391
+ [self scrollViewDidScroll ];
392
+ }] rate: 2 ];
393
393
CCActionCallFunc* callFunc = [CCActionCallFunc actionWithTarget: self selector: @selector (yAnimationDone )];
394
394
action = [CCActionSequence actions: action, callFunc, nil ];
395
395
action.tag = kCCScrollViewActionYTag ;
@@ -399,6 +399,9 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
399
399
}
400
400
else
401
401
{
402
+ #ifdef __CC_PLATFORM_MAC
403
+ _lastPosition = self.scrollPosition ;
404
+ #endif
402
405
[_contentNode stopActionByTag: kCCScrollViewActionXTag ];
403
406
[_contentNode stopActionByTag: kCCScrollViewActionYTag ];
404
407
_contentNode.position = ccpMult (newPos, -1 );
@@ -453,15 +456,32 @@ - (void) panLayerToTarget:(CGPoint) newPos
453
456
if (newPos.y > self.maxScrollY ) newPos.y = self.maxScrollY ;
454
457
if (newPos.y < self.minScrollY ) newPos.y = self.minScrollY ;
455
458
}
456
-
459
+ [ self scrollViewDidScroll ];
457
460
_contentNode.position = ccpMult (newPos, -1 );
458
461
}
459
462
460
463
- (void ) update : (CCTime)df
461
464
{
462
465
float fps = 1.0 /df;
463
466
float p = 60 /fps;
464
-
467
+
468
+ if (! CGPointEqualToPoint (_velocity, CGPointZero) ) {
469
+ [self scrollViewDidScroll ];
470
+ } else {
471
+
472
+ #ifdef __CC_PLATFORM_IOS
473
+ if ( _decelerating && !(_animatingX || _animatingY)) {
474
+ [self scrollViewDidEndDecelerating ];
475
+ _decelerating = NO ;
476
+ }
477
+ #elif defined(__CC_PLATFORM_MAC)
478
+ if ( _decelerating && CGPointEqualToPoint (_lastPosition, self.scrollPosition )) {
479
+ [self scrollViewDidEndDecelerating ];
480
+ _decelerating = NO ;
481
+ }
482
+ #endif
483
+ }
484
+
465
485
if (!_isPanning)
466
486
{
467
487
if (_velocity.x != 0 || _velocity.y != 0 )
@@ -553,6 +573,7 @@ - (void)handlePan:(UIGestureRecognizer *)gestureRecognizer
553
573
554
574
if (pgr.state == UIGestureRecognizerStateBegan)
555
575
{
576
+ [self scrollViewWillBeginDragging ];
556
577
_animatingX = NO ;
557
578
_animatingY = NO ;
558
579
_rawTranslationStart = rawTranslation;
@@ -581,6 +602,7 @@ - (void)handlePan:(UIGestureRecognizer *)gestureRecognizer
581
602
}
582
603
else if (pgr.state == UIGestureRecognizerStateEnded)
583
604
{
605
+
584
606
// Calculate the velocity in node space
585
607
CGPoint ref = [dir convertToGL: CGPointZero];
586
608
ref = [self convertToNodeSpace: ref];
@@ -595,6 +617,7 @@ - (void)handlePan:(UIGestureRecognizer *)gestureRecognizer
595
617
// Check if scroll directions has been disabled
596
618
if (!_horizontalScrollEnabled) _velocity.x = 0 ;
597
619
if (!_verticalScrollEnabled) _velocity.y = 0 ;
620
+ [self scrollViewDidEndDraggingAndWillDecelerate: !CGPointEqualToPoint (_velocity, CGPointZero)];
598
621
599
622
// Setup a target if paging is enabled
600
623
if (_pagingEnabled)
@@ -633,7 +656,8 @@ - (void)handlePan:(UIGestureRecognizer *)gestureRecognizer
633
656
634
657
_velocity = CGPointZero;
635
658
}
636
-
659
+ [self scrollViewWillBeginDecelerating ];
660
+ _decelerating = YES ;
637
661
_isPanning = NO ;
638
662
}
639
663
else if (pgr.state == UIGestureRecognizerStateCancelled)
@@ -749,11 +773,30 @@ - (void) onExitTransitionDidStart
749
773
750
774
- (void )scrollWheel : (NSEvent *)theEvent
751
775
{
752
- CCDirector* dir = [CCDirector sharedDirector ];
753
-
776
+ CCDirector* dir = [CCDirector sharedDirector ];
777
+
754
778
float deltaX = theEvent.deltaX ;
755
779
float deltaY = theEvent.deltaY ;
756
-
780
+
781
+ [self scrollViewDidScroll ];
782
+
783
+ switch (theEvent.phase ) {
784
+ case NSEventPhaseBegan:
785
+ [self scrollViewWillBeginDragging ];
786
+ break ;
787
+ case NSEventPhaseEnded:
788
+ // TODO: add logic to determine if it will decelerate
789
+ [self scrollViewDidEndDraggingAndWillDecelerate: YES ];
790
+ _decelerating = YES ;
791
+ default :
792
+ break ;
793
+ }
794
+
795
+ if (theEvent.momentumPhase == NSEventPhaseBegan)
796
+ {
797
+ [self scrollViewWillBeginDecelerating ];
798
+ }
799
+
757
800
// Calculate the delta in node space
758
801
CGPoint ref = [dir convertToGL: CGPointZero];
759
802
ref = [self convertToNodeSpace: ref];
@@ -768,6 +811,7 @@ - (void)scrollWheel:(NSEvent *)theEvent
768
811
// Flip coordinates
769
812
if (_flipYCoordinates) delta.y = -delta.y ;
770
813
delta.x = -delta.x ;
814
+
771
815
772
816
// Handle disabled x/y axis
773
817
if (!_horizontalScrollEnabled) delta.x = 0 ;
@@ -818,10 +862,55 @@ - (void)scrollWheel:(NSEvent *)theEvent
818
862
// Update scroll position
819
863
CGPoint scrollPos = self.scrollPosition ;
820
864
scrollPos = ccpAdd (delta, scrollPos);
821
- self.scrollPosition = scrollPos;
865
+ self.scrollPosition = scrollPos;
822
866
}
823
867
}
824
868
825
869
#endif
826
870
871
+
872
+ #pragma mark - CCScrollViewDelegate Helpers
873
+
874
+ - (void )scrollViewDidScroll
875
+ {
876
+ if ( [self .delegate respondsToSelector: @selector (scrollViewDidScroll: )] )
877
+ {
878
+ [self .delegate scrollViewDidScroll: self ];
879
+ }
880
+ }
881
+
882
+ - (void )scrollViewWillBeginDragging
883
+ {
884
+ if ( [self .delegate respondsToSelector: @selector (scrollViewWillBeginDragging: )])
885
+ {
886
+ [self .delegate scrollViewWillBeginDragging: self ];
887
+ }
888
+ }
889
+ - (void )scrollViewDidEndDraggingAndWillDecelerate : (BOOL )decelerate
890
+ {
891
+ if ([self .delegate respondsToSelector: @selector (scrollViewDidEndDragging:willDecelerate: )])
892
+ {
893
+ [self .delegate scrollViewDidEndDragging: self
894
+ willDecelerate: decelerate];
895
+ }
896
+ }
897
+ - (void )scrollViewWillBeginDecelerating
898
+ {
899
+ if ( !_pagingEnabled )
900
+ {
901
+ if ( [self .delegate respondsToSelector: @selector (scrollViewWillBeginDecelerating: )])
902
+ {
903
+ [self .delegate scrollViewWillBeginDecelerating: self ];
904
+ }
905
+ }
906
+
907
+ }
908
+ - (void )scrollViewDidEndDecelerating
909
+ {
910
+ if ( [self .delegate respondsToSelector: @selector (scrollViewDidEndDecelerating: )])
911
+ {
912
+ [self .delegate scrollViewDidEndDecelerating: self ];
913
+ }
914
+ }
915
+
827
916
@end
0 commit comments