MPUserDynamicTransition.m 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. //
  2. // MPUserDynamicTransition.m
  3. //
  4. // Created by Maple on 2019/12/5.
  5. //
  6. #import "MPUserDynamicTransition.h"
  7. #import <ZFPlayer/ZFUtilities.h>
  8. @interface MPUserDynamicTransition ()
  9. @property (nonatomic, assign) NSTimeInterval duration;
  10. @property (nonatomic, strong) UIView *startView;
  11. @property (nonatomic, strong) UIImage *startImage;
  12. @property (nonatomic, strong) UICollectionView *collectionView;
  13. @property (nonatomic, assign) NSInteger index;
  14. @property (nonatomic, assign) CGFloat endX;
  15. @property (nonatomic, assign) UINavigationControllerOperation operation;
  16. @end
  17. @implementation MPUserDynamicTransition
  18. + (instancetype)animationWithDuration:(NSTimeInterval)duration
  19. startView:(UIView *)startView
  20. startImage:(UIImage *)startImage
  21. endX: (CGFloat)endX
  22. operation:(UINavigationControllerOperation)operation
  23. {
  24. MPUserDynamicTransition *transition = [[self alloc] init];
  25. transition.duration = duration;
  26. transition.startView = startView;
  27. transition.startImage = startImage;
  28. transition.endX = endX;
  29. transition.operation = operation;
  30. return transition;
  31. }
  32. - (NSTimeInterval)transitionDuration:(nullable id<UIViewControllerContextTransitioning>)transitionContext {
  33. return self.duration;
  34. }
  35. - (void)animateTransition:(nonnull id<UIViewControllerContextTransitioning>)transitionContext {
  36. if (self.operation == UINavigationControllerOperationPush) {
  37. [self startPushAnimation: transitionContext];
  38. }else {
  39. [self startPopAnimation: transitionContext];
  40. }
  41. }
  42. - (void)startPushAnimation: (nonnull id<UIViewControllerContextTransitioning>)transitionContext
  43. {
  44. UIView *contentView = [transitionContext containerView];
  45. // 获取 fromView 和 toView
  46. UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
  47. UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
  48. [contentView addSubview:fromView];
  49. [contentView addSubview:toView];
  50. UIImageView *imageView = [[UIImageView alloc] init];
  51. imageView.contentMode = UIViewContentModeScaleAspectFill;
  52. imageView.clipsToBounds = YES;
  53. imageView.layer.cornerRadius = self.startView.bounds.size.width * 0.5;
  54. imageView.layer.masksToBounds = YES;
  55. imageView.image = self.startImage;
  56. CGRect winFrame = CGRectZero;
  57. if (self.startView) {
  58. winFrame = [self.startView convertRect:self.startView.bounds toView:nil];
  59. }
  60. imageView.frame = winFrame;
  61. toView.center = imageView.center;
  62. CGFloat scale = 56.0 / ZFPlayer_ScreenWidth;
  63. toView.transform = CGAffineTransformMakeScale(scale, scale);
  64. [UIView animateWithDuration:self.duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  65. toView.transform = CGAffineTransformIdentity;
  66. toView.center = CGPointMake(ZFPlayer_ScreenWidth * 0.5, ZFPlayer_ScreenHeight * 0.5);
  67. } completion:^(BOOL finished) {
  68. // 结束动画
  69. [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
  70. }];
  71. }
  72. - (void)startPopAnimation: (nonnull id<UIViewControllerContextTransitioning>)transitionContext
  73. {
  74. UIView *contentView = [transitionContext containerView];
  75. // 获取 fromView 和 toView
  76. UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
  77. UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
  78. UIView *whiteCoverView = [[UIView alloc] init];
  79. whiteCoverView.backgroundColor = [UIColor blackColor];
  80. whiteCoverView.frame = CGRectMake(0, 0, ZFPlayer_ScreenWidth, ZFPlayer_ScreenHeight);
  81. whiteCoverView.alpha = 0;
  82. [contentView addSubview:toView];
  83. [contentView addSubview:whiteCoverView];
  84. [contentView addSubview:fromView];
  85. UIImageView *imageView = [[UIImageView alloc] init];
  86. imageView.contentMode = UIViewContentModeScaleAspectFill;
  87. imageView.clipsToBounds = YES;
  88. imageView.image = self.startImage;
  89. imageView.layer.cornerRadius = ZFPlayer_ScreenWidth * 0.5;
  90. CGFloat top = (ZFPlayer_ScreenHeight - ZFPlayer_ScreenWidth) * 0.5;
  91. CGRect winFrame = CGRectMake(0, top, ZFPlayer_ScreenWidth, ZFPlayer_ScreenWidth);
  92. imageView.frame = winFrame;
  93. imageView.hidden = YES;
  94. [contentView addSubview:imageView];
  95. CGFloat targetCorner = 0;
  96. CGRect targetFrame = CGRectZero;
  97. if (self.startView) {
  98. targetFrame = [self.startView convertRect:self.startView.bounds toView:nil];
  99. targetFrame = CGRectMake(self.endX, targetFrame.origin.y, targetFrame.size.width, targetFrame.size.height);
  100. targetCorner = self.startView.bounds.size.width * 0.5;
  101. }
  102. dispatch_block_t block = dispatch_block_create(0, ^{
  103. imageView.hidden = NO;
  104. toView.alpha = 1.0f;
  105. fromView.transform = CGAffineTransformIdentity;
  106. fromView.alpha = 0.0f;
  107. whiteCoverView.alpha = 0.4;
  108. [UIView animateWithDuration:self.duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  109. whiteCoverView.alpha = 0;
  110. imageView.frame = targetFrame;
  111. imageView.layer.cornerRadius = targetCorner;
  112. } completion:^(BOOL finished) {
  113. [imageView removeFromSuperview];
  114. [whiteCoverView removeFromSuperview];
  115. // 结束动画
  116. [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
  117. }];
  118. });
  119. if (self.isInteracting) {
  120. whiteCoverView.alpha = 1;
  121. [UIView animateWithDuration:self.duration animations:^{
  122. whiteCoverView.alpha = 0.4;
  123. fromView.transform = CGAffineTransformScale(fromView.transform, 0.9, 0.9);
  124. fromView.transform = CGAffineTransformTranslate(fromView.transform, 0, ZFPlayer_ScreenHeight * 0.5);
  125. } completion:^(BOOL finished) {
  126. if (self.isComplete) {
  127. block();
  128. }else {
  129. [imageView removeFromSuperview];
  130. [whiteCoverView removeFromSuperview];
  131. // 结束动画
  132. [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
  133. }
  134. }];
  135. }else {
  136. block();
  137. }
  138. }
  139. - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
  140. // 标记转场结束
  141. id<UIViewControllerContextTransitioning> transitionContext = [anim valueForKey:@"transitionContext"];
  142. // 结束动画
  143. [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
  144. }
  145. @end