react-native-navigation的迁移库

DisplayLinkAnimator.m 2.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #import "DisplayLinkAnimator.h"
  2. @implementation DisplayLinkAnimator {
  3. NSArray<id<DisplayLinkAnimatorDelegate>>* _animators;
  4. NSMutableArray<id<DisplayLinkAnimatorDelegate>>* _activeAnimators;
  5. CADisplayLink* _displayLink;
  6. NSDate* _startDate;
  7. CGFloat _duration;
  8. }
  9. - (instancetype)initWithDisplayLinkAnimators:(NSArray<id<DisplayLinkAnimatorDelegate>> *)displayLinkAnimators duration:(CGFloat)duration {
  10. self = [super init];
  11. _animators = displayLinkAnimators;
  12. _activeAnimators = [NSMutableArray arrayWithArray:displayLinkAnimators];
  13. _duration = [self maxDuration:displayLinkAnimators];
  14. return self;
  15. }
  16. - (instancetype)initWithDisplayLinkAnimator:(id<DisplayLinkAnimatorDelegate>)displayLinkAnimator duration:(CGFloat)duration {
  17. self = [self initWithDisplayLinkAnimators:@[displayLinkAnimator] duration:duration];
  18. return self;
  19. }
  20. - (void)start {
  21. _startDate = NSDate.date;
  22. _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_displayLinkDidTick:)];
  23. [_displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSDefaultRunLoopMode];
  24. }
  25. - (CGFloat)maxDuration:(NSArray<id<DisplayLinkAnimatorDelegate>> *)displayLinkAnimators {
  26. CGFloat maxDuration = 0;
  27. for (id<DisplayLinkAnimatorDelegate> animator in displayLinkAnimators) {
  28. if (animator.maxDuration > maxDuration) {
  29. maxDuration = animator.maxDuration;
  30. }
  31. }
  32. return maxDuration;
  33. }
  34. - (void)_displayLinkDidTick:(CADisplayLink*)displayLink {
  35. NSTimeInterval elapsed = [NSDate.date timeIntervalSinceDate:_startDate];
  36. if (elapsed > _duration) {
  37. [self updateAnimators:_duration];
  38. [self end];
  39. [displayLink invalidate];
  40. if (_completion) {
  41. _completion();
  42. _completion = nil;
  43. }
  44. return;
  45. }
  46. [self updateAnimators:elapsed];
  47. }
  48. - (void)updateAnimators:(NSTimeInterval)elapsed {
  49. for (int i = 0; i < _activeAnimators.count; i++) {
  50. id<DisplayLinkAnimatorDelegate> animator = _activeAnimators[i];
  51. if (elapsed < animator.maxDuration) {
  52. [animator updateAnimations:elapsed];
  53. } else {
  54. [self deactivateAnimator:animator];
  55. }
  56. }
  57. }
  58. - (void)deactivateAnimator:(id<DisplayLinkAnimatorDelegate>)animator {
  59. [animator end];
  60. [_activeAnimators removeObject:animator];
  61. }
  62. - (void)end {
  63. for (int i = 0; i < _activeAnimators.count; i++) {
  64. id<DisplayLinkAnimatorDelegate> animator = _activeAnimators[i];
  65. [animator end];
  66. }
  67. _activeAnimators = nil;
  68. }
  69. @end