diff --git a/lib/ios/AnimatedImageView.h b/lib/ios/AnimatedImageView.h index 096eadc0e79..8a76ede3b4d 100644 --- a/lib/ios/AnimatedImageView.h +++ b/lib/ios/AnimatedImageView.h @@ -3,4 +3,7 @@ @interface AnimatedImageView : AnimatedReactView +@property(nonatomic, strong) UIImageView *fromImageView; +@property(nonatomic, strong) UIImageView *toImageView; + @end diff --git a/lib/ios/AnimatedImageView.m b/lib/ios/AnimatedImageView.m index b201647a740..410aec435a6 100644 --- a/lib/ios/AnimatedImageView.m +++ b/lib/ios/AnimatedImageView.m @@ -1,14 +1,74 @@ #import "AnimatedImageView.h" +#import "BoundsTransition.h" +#import "CenterTransition.h" +#import "UIImageView+Transition.h" -@implementation AnimatedImageView +@implementation AnimatedImageView { + SharedElementTransitionOptions *_transitionOptions; + CGRect _originalBounds; + CGPoint _originalCenter; + UIViewContentMode _originalContentMode; +} - (instancetype)initElement:(UIView *)element toElement:(UIView *)toElement transitionOptions:(SharedElementTransitionOptions *)transitionOptions { self = [super initElement:element toElement:toElement transitionOptions:transitionOptions]; - self.contentMode = element.contentMode; + + _transitionOptions = transitionOptions; + + _fromImageView = [self findImageView:element]; + _toImageView = [self findImageView:toElement]; + _originalBounds = _fromImageView.bounds; + _originalContentMode = _fromImageView.contentMode; + _originalCenter = _fromImageView.center; + _fromImageView.autoresizingMask = + UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; return self; } +- (UIImageView *)findImageView:(UIView *)view { + if ([view isKindOfClass:UIImageView.class]) { + return (UIImageView *)view; + } + + for (UIView *subview in view.subviews) { + return [self findImageView:subview]; + } + + return nil; +} + +- (NSArray> *)extraAnimations { + NSMutableArray *animations = NSMutableArray.new; + CGFloat startDelay = [_transitionOptions.startDelay withDefault:0]; + CGFloat duration = [_transitionOptions.duration withDefault:300]; + id interpolator = _transitionOptions.interpolator; + + [animations addObject:[[BoundsTransition alloc] initWithView:_fromImageView + from:_fromImageView.resolveBounds + to:_toImageView.resolveBounds + startDelay:startDelay + duration:duration + interpolator:interpolator]]; + + [animations addObject:[[CenterTransition alloc] initWithView:_fromImageView + from:_fromImageView.center + to:_toImageView.center + startDelay:startDelay + duration:duration + interpolator:interpolator]]; + _fromImageView.contentMode = UIViewContentModeScaleToFill; + + return animations; +} + +- (void)reset { + [super reset]; + _fromImageView.bounds = _originalBounds; + _fromImageView.contentMode = _originalContentMode; + _fromImageView.center = _originalCenter; +} + @end diff --git a/lib/ios/AnimatedReactView.h b/lib/ios/AnimatedReactView.h index 986d002e85d..b9fa3f6eaa9 100644 --- a/lib/ios/AnimatedReactView.h +++ b/lib/ios/AnimatedReactView.h @@ -1,3 +1,4 @@ +#import "DisplayLinkAnimation.h" #import "RNNViewLocation.h" #import "SharedElementTransitionOptions.h" @@ -14,4 +15,6 @@ - (void)reset; +- (NSArray> *)extraAnimations; + @end diff --git a/lib/ios/AnimatedReactView.m b/lib/ios/AnimatedReactView.m index b934929ad45..02f5a1955b0 100644 --- a/lib/ios/AnimatedReactView.m +++ b/lib/ios/AnimatedReactView.m @@ -7,10 +7,12 @@ @implementation AnimatedReactView { CGRect _originalFrame; CGFloat _originalCornerRadius; CGRect _originalLayoutBounds; + CGPoint _originalCenter; CATransform3D _originalTransform; UIView *_toElement; UIColor *_fromColor; NSInteger _zIndex; + UIViewContentMode _originalContentMode; SharedElementTransitionOptions *_transitionOptions; } @@ -45,34 +47,40 @@ - (NSNumber *)reactZIndex { - (void)hijackReactElement:(UIView *)element { _reactView = element; + _originalContentMode = _reactView.contentMode; _originalFrame = _reactView.frame; _originalTransform = element.layer.transform; - _originalLayoutBounds = element.layer.bounds; - self.contentMode = element.contentMode; - self.frame = self.location.fromFrame; _originalParent = _reactView.superview; + _originalCenter = _reactView.center; _originalCornerRadius = element.layer.cornerRadius; - _reactView.frame = self.bounds; + _originalTransform = _reactView.layer.transform; + _originalLayoutBounds = _reactView.bounds; _reactView.layer.transform = CATransform3DIdentity; _reactView.layer.cornerRadius = self.location.fromCornerRadius; + [self addSubview:_reactView]; } +- (void)layoutSubviews { + [super layoutSubviews]; + self.reactView.bounds = self.bounds; + self.reactView.center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2); +} + - (void)reset { - _reactView.frame = _originalFrame; + _reactView.center = _originalCenter; _reactView.layer.cornerRadius = _originalCornerRadius; _reactView.bounds = _originalLayoutBounds; - _reactView.layer.bounds = _originalLayoutBounds; _reactView.layer.transform = _originalTransform; + _reactView.contentMode = _originalContentMode; [_originalParent insertSubview:_reactView atIndex:self.location.index]; _toElement.hidden = NO; _reactView.backgroundColor = _fromColor; [self removeFromSuperview]; } -- (void)layoutSubviews { - [super layoutSubviews]; - _reactView.frame = self.bounds; +- (NSArray> *)extraAnimations { + return @[]; } @end diff --git a/lib/ios/AnimatedUIImageView.h b/lib/ios/AnimatedUIImageView.h new file mode 100644 index 00000000000..d3f9379d258 --- /dev/null +++ b/lib/ios/AnimatedUIImageView.h @@ -0,0 +1,5 @@ +#import "AnimatedImageView.h" + +@interface AnimatedUIImageView : AnimatedImageView + +@end diff --git a/lib/ios/AnimatedUIImageView.m b/lib/ios/AnimatedUIImageView.m new file mode 100644 index 00000000000..3dd662ff4ff --- /dev/null +++ b/lib/ios/AnimatedUIImageView.m @@ -0,0 +1,8 @@ +#import "AnimatedUIImageView.h" + +@implementation AnimatedUIImageView + +- (void)layoutSubviews { +} + +@end diff --git a/lib/ios/AnimatedViewFactory.m b/lib/ios/AnimatedViewFactory.m index a33435c9e32..0afcfd6b3c0 100644 --- a/lib/ios/AnimatedViewFactory.m +++ b/lib/ios/AnimatedViewFactory.m @@ -1,6 +1,7 @@ #import "AnimatedViewFactory.h" #import "AnimatedImageView.h" #import "AnimatedTextView.h" +#import "AnimatedUIImageView.h" #import "UIVIew+Utils.h" @implementation AnimatedViewFactory @@ -13,6 +14,10 @@ + (AnimatedReactView *)createFromElement:(UIView *)element return [[AnimatedImageView alloc] initElement:element toElement:toElement transitionOptions:transitionOptions]; + case ViewTypeUIImage: + return [[AnimatedUIImageView alloc] initElement:element + toElement:toElement + transitionOptions:transitionOptions]; case ViewTypeText: return [[AnimatedTextView alloc] initElement:element toElement:toElement diff --git a/lib/ios/BoundsTransition.h b/lib/ios/BoundsTransition.h new file mode 100644 index 00000000000..ce30bc48da1 --- /dev/null +++ b/lib/ios/BoundsTransition.h @@ -0,0 +1,15 @@ +#import "ElementBaseTransition.h" + +@interface BoundsTransition : ElementBaseTransition + +@property(nonatomic) CGRect fromBounds; +@property(nonatomic) CGRect toBounds; + +- (instancetype)initWithView:(UIView *)view + from:(CGRect)from + to:(CGRect)to + startDelay:(NSTimeInterval)startDelay + duration:(NSTimeInterval)duration + interpolator:(id)interpolator; + +@end diff --git a/lib/ios/BoundsTransition.m b/lib/ios/BoundsTransition.m new file mode 100644 index 00000000000..2f5d1786f96 --- /dev/null +++ b/lib/ios/BoundsTransition.m @@ -0,0 +1,30 @@ +#import "BoundsTransition.h" + +@implementation BoundsTransition + +- (instancetype)initWithView:(UIView *)view + from:(CGRect)from + to:(CGRect)to + startDelay:(NSTimeInterval)startDelay + duration:(NSTimeInterval)duration + interpolator:(id)interpolator { + self = [super initWithView:view + startDelay:startDelay + duration:duration + interpolator:interpolator]; + _fromBounds = from; + _toBounds = to; + return self; +} + +- (CATransform3D)animateWithProgress:(CGFloat)p { + CGRect toBounds = [RNNInterpolator fromRect:_fromBounds + toRect:_toBounds + precent:p + interpolator:self.interpolator]; + self.view.bounds = toBounds; + + return CATransform3DIdentity; +} + +@end diff --git a/lib/ios/CenterTransition.h b/lib/ios/CenterTransition.h new file mode 100644 index 00000000000..0dc03319d17 --- /dev/null +++ b/lib/ios/CenterTransition.h @@ -0,0 +1,15 @@ +#import "ElementBaseTransition.h" + +@interface CenterTransition : ElementBaseTransition + +@property(nonatomic) CGPoint fromCenter; +@property(nonatomic) CGPoint toCenter; + +- (instancetype)initWithView:(UIView *)view + from:(CGPoint)from + to:(CGPoint)to + startDelay:(NSTimeInterval)startDelay + duration:(NSTimeInterval)duration + interpolator:(id)interpolator; + +@end diff --git a/lib/ios/CenterTransition.m b/lib/ios/CenterTransition.m new file mode 100644 index 00000000000..8625aac1063 --- /dev/null +++ b/lib/ios/CenterTransition.m @@ -0,0 +1,29 @@ +#import "CenterTransition.h" + +@implementation CenterTransition + +- (instancetype)initWithView:(UIView *)view + from:(CGPoint)from + to:(CGPoint)to + startDelay:(NSTimeInterval)startDelay + duration:(NSTimeInterval)duration + interpolator:(id)interpolator { + self = [super initWithView:view + startDelay:startDelay + duration:duration + interpolator:interpolator]; + self.fromCenter = from; + self.toCenter = to; + return self; +} + +- (CATransform3D)animateWithProgress:(CGFloat)p { + CGPoint toCenter = [RNNInterpolator fromPoint:self.fromCenter + toPoint:self.toCenter + precent:p + interpolator:self.interpolator]; + self.view.center = toCenter; + return CATransform3DIdentity; +} + +@end diff --git a/lib/ios/PathTransition.h b/lib/ios/PathTransition.h new file mode 100644 index 00000000000..ba46b232f15 --- /dev/null +++ b/lib/ios/PathTransition.h @@ -0,0 +1,17 @@ +#import "RectTransition.h" + +@interface PathTransition : RectTransition + +@property(nonatomic) CGFloat fromCornerRadius; +@property(nonatomic) CGFloat toCornerRadius; + +- (instancetype)initWithView:(UIView *)view + fromPath:(CGRect)fromPath + toPath:(CGRect)toPath + fromCornerRadius:(CGFloat)fromCornerRadius + toCornerRadius:(CGFloat)toCornerRadius + startDelay:(NSTimeInterval)startDelay + duration:(NSTimeInterval)duration + interpolator:(id)interpolator; + +@end diff --git a/lib/ios/PathTransition.m b/lib/ios/PathTransition.m new file mode 100644 index 00000000000..62a9bb3a66f --- /dev/null +++ b/lib/ios/PathTransition.m @@ -0,0 +1,40 @@ +#import "PathTransition.h" + +@implementation PathTransition + +- (instancetype)initWithView:(UIView *)view + fromPath:(CGRect)fromPath + toPath:(CGRect)toPath + fromCornerRadius:(CGFloat)fromCornerRadius + toCornerRadius:(CGFloat)toCornerRadius + startDelay:(NSTimeInterval)startDelay + duration:(NSTimeInterval)duration + interpolator:(id)interpolator { + self = [super initWithView:view + from:fromPath + to:toPath + startDelay:startDelay + duration:duration + interpolator:interpolator]; + self.fromCornerRadius = fromCornerRadius; + self.toCornerRadius = toCornerRadius; + + return self; +} + +- (CATransform3D)animateWithProgress:(CGFloat)p { + CGRect toPath = [RNNInterpolator fromRect:self.from + toRect:self.to + precent:p + interpolator:self.interpolator]; + CGFloat toRadius = [RNNInterpolator fromFloat:self.fromCornerRadius + toFloat:self.toCornerRadius + precent:p + interpolator:self.interpolator]; + CAShapeLayer *mask = [CAShapeLayer new]; + mask.path = [UIBezierPath bezierPathWithRoundedRect:toPath cornerRadius:toRadius].CGPath; + self.view.layer.mask = mask; + return CATransform3DIdentity; +} + +@end diff --git a/lib/ios/RNNInterpolator.h b/lib/ios/RNNInterpolator.h index be553b76063..9b61da7b4ce 100644 --- a/lib/ios/RNNInterpolator.h +++ b/lib/ios/RNNInterpolator.h @@ -3,6 +3,11 @@ @interface RNNInterpolator : NSObject ++ (CGPoint)fromPoint:(CGPoint)from + toPoint:(CGPoint)to + precent:(CGFloat)p + interpolator:(id)interpolator; + + (UIColor *)fromColor:(UIColor *)fromColor toColor:(UIColor *)toColor precent:(CGFloat)precent; + (CGFloat)fromFloat:(CGFloat)from diff --git a/lib/ios/RNNInterpolator.m b/lib/ios/RNNInterpolator.m index 8b5fb0bed54..5aa7a9328e1 100644 --- a/lib/ios/RNNInterpolator.m +++ b/lib/ios/RNNInterpolator.m @@ -3,6 +3,14 @@ @implementation RNNInterpolator ++ (CGPoint)fromPoint:(CGPoint)from + toPoint:(CGPoint)to + precent:(CGFloat)p + interpolator:(id)interpolator { + return CGPointMake(RNNInterpolate(from.x, to.x, p, interpolator), + RNNInterpolate(from.y, to.y, p, interpolator)); +} + + (UIColor *)fromColor:(UIColor *)fromColor toColor:(UIColor *)toColor precent:(CGFloat)precent { return [fromColor ?: UIColor.clearColor interpolateToValue:toColor ?: UIColor.clearColor diff --git a/lib/ios/RNNScreenTransitionsCreator.h b/lib/ios/RNNScreenTransitionsCreator.h index 5a22cf67f44..b854e36dcf6 100644 --- a/lib/ios/RNNScreenTransitionsCreator.h +++ b/lib/ios/RNNScreenTransitionsCreator.h @@ -8,8 +8,6 @@ containerView:(UIView *)containerView contentTransition:(RNNEnterExitAnimation *)contentTransitionOptions elementTransitions: - (NSArray *)elementTransitionsOptions - sharedElementTransitions: - (NSArray *)sharedElementTransitionsOptions; + (NSArray *)elementTransitionsOptions; @end diff --git a/lib/ios/RNNScreenTransitionsCreator.m b/lib/ios/RNNScreenTransitionsCreator.m index c82a7329fee..3176e6f722c 100644 --- a/lib/ios/RNNScreenTransitionsCreator.m +++ b/lib/ios/RNNScreenTransitionsCreator.m @@ -1,7 +1,7 @@ #import "RNNScreenTransitionsCreator.h" #import "DisplayLinkAnimatorDelegate.h" #import "ElementTransitionsCreator.h" -#import "SharedElementTransitionsCreator.h" +#import "SharedElementAnimator.h" @implementation RNNScreenTransitionsCreator @@ -10,19 +10,11 @@ + (NSArray *)createTransitionsFromVC:(UIViewController *)fromVC containerView:(UIView *)containerView contentTransition:(RNNEnterExitAnimation *)contentTransitionOptions elementTransitions: - (NSArray *)elementTransitionsOptions - sharedElementTransitions: - (NSArray *)sharedElementTransitionsOptions { + (NSArray *)elementTransitionsOptions { NSArray *elementTransitions = [ElementTransitionsCreator create:elementTransitionsOptions fromVC:fromVC toVC:toVC containerView:containerView]; - NSArray *sharedElementTransitions = - [SharedElementTransitionsCreator create:sharedElementTransitionsOptions - fromVC:fromVC - toVC:toVC - containerView:containerView]; - id enterTransition = [ElementTransitionsCreator createTransition:contentTransitionOptions.enter view:toVC.view @@ -35,9 +27,8 @@ + (NSArray *)createTransitionsFromVC:(UIViewController *)fromVC containerView:containerView]; } - return [[[NSArray arrayWithObjects:enterTransition, exitTransition, nil] - arrayByAddingObjectsFromArray:elementTransitions] - arrayByAddingObjectsFromArray:sharedElementTransitions]; + return [[NSArray arrayWithObjects:enterTransition, exitTransition, nil] + arrayByAddingObjectsFromArray:elementTransitions]; } @end diff --git a/lib/ios/RNNViewLocation.h b/lib/ios/RNNViewLocation.h index 8a5ae2e4cfb..0cc2a510c90 100644 --- a/lib/ios/RNNViewLocation.h +++ b/lib/ios/RNNViewLocation.h @@ -12,6 +12,13 @@ @property(nonatomic) CATransform3D fromTransform; @property(nonatomic) CATransform3D toTransform; +@property(nonatomic) CGRect fromBounds; +@property(nonatomic) CGRect toBounds; +@property(nonatomic) CGPoint fromCenter; +@property(nonatomic) CGPoint toCenter; +@property(nonatomic) CGRect fromPath; +@property(nonatomic) CGRect toPath; + - (instancetype)initWithFromElement:(UIView *)fromElement toElement:(UIView *)toElement; @end diff --git a/lib/ios/RNNViewLocation.m b/lib/ios/RNNViewLocation.m index 6b9981dbc6d..2e601239eb5 100644 --- a/lib/ios/RNNViewLocation.m +++ b/lib/ios/RNNViewLocation.m @@ -16,9 +16,33 @@ - (instancetype)initWithFromElement:(UIView *)fromElement toElement:(UIView *)to fromElement.layer.cornerRadius ?: [self getClippedCornerRadius:fromElement]; self.toCornerRadius = toElement.layer.cornerRadius ?: [self getClippedCornerRadius:toElement]; self.index = [fromElement.superview.subviews indexOfObject:fromElement]; + + self.fromBounds = [self convertViewBounds:fromElement]; + self.toBounds = [self convertViewBounds:toElement]; + self.fromCenter = [self convertViewCenter:fromElement]; + self.toCenter = [self convertViewCenter:toElement]; + self.fromPath = [self resolveViewPath:fromElement withSuperView:fromElement.superview]; + self.toPath = [self resolveViewPath:toElement withSuperView:toElement.superview]; + return self; } +- (CGRect)resolveViewPath:(UIView *)view withSuperView:(UIView *)superView { + const CGRect childFrame = [superView convertRect:view.bounds toView:superView.superview]; + if (superView) { + const CGRect intersection = CGRectIntersection(superView.bounds, childFrame); + if (!CGRectEqualToRect(intersection, view.frame) && superView.clipsToBounds) { + return CGRectMake(-childFrame.origin.x, -childFrame.origin.y, + intersection.size.width + intersection.origin.x, + intersection.size.height + intersection.origin.y); + } else { + [self resolveViewPath:view withSuperView:superView.superview]; + } + } + + return view.bounds; +} + - (CGFloat)getClippedCornerRadius:(UIView *)view { if (view.layer.cornerRadius > 0 && view.clipsToBounds) { return view.layer.cornerRadius; @@ -30,21 +54,23 @@ - (CGFloat)getClippedCornerRadius:(UIView *)view { } - (CATransform3D)getTransform:(UIView *)view { - if (view) { - if (!CATransform3DEqualToTransform(view.layer.transform, CATransform3DIdentity)) { - return view.layer.transform; - } else { - return [self getTransform:view.superview]; - } - } + return view.layer.transform; +} - return CATransform3DIdentity; +- (CGPoint)convertViewCenter:(UIView *)view { + CGPoint center = [view.superview convertPoint:view.center toView:nil]; + return center; } - (CGRect)convertViewFrame:(UIView *)view { return [view.superview convertRect:view.frame toView:nil]; } +- (CGRect)convertViewBounds:(UIView *)view { + CGRect convertedBounds = [view.superview convertRect:view.bounds toView:nil]; + return CGRectMake(0, 0, convertedBounds.size.width, convertedBounds.size.height); +} + - (CGFloat)getViewAngle:(UIView *)view { CGFloat radians = atan2f(view.transform.b, view.transform.a); return radians; diff --git a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj index 364b9177e51..c95bafab7fd 100644 --- a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj +++ b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj @@ -237,6 +237,14 @@ 50644A2120E11A720026709C /* Constants.m in Sources */ = {isa = PBXBuildFile; fileRef = 50644A1F20E11A720026709C /* Constants.m */; }; 506A2B1420973DFD00F43A95 /* RNNErrorHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 506A2B1220973DFD00F43A95 /* RNNErrorHandler.h */; }; 506A2B1520973DFD00F43A95 /* RNNErrorHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 506A2B1320973DFD00F43A95 /* RNNErrorHandler.m */; }; + 506BF65C2600AE4200A22755 /* CenterTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 506BF65A2600AE4200A22755 /* CenterTransition.h */; }; + 506BF65D2600AE4200A22755 /* CenterTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 506BF65B2600AE4200A22755 /* CenterTransition.m */; }; + 506BF6622600AE7600A22755 /* BoundsTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 506BF6602600AE7600A22755 /* BoundsTransition.h */; }; + 506BF6632600AE7600A22755 /* BoundsTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 506BF6612600AE7600A22755 /* BoundsTransition.m */; }; + 506BF6982600B72D00A22755 /* UIImageView+Transition.h in Headers */ = {isa = PBXBuildFile; fileRef = 506BF6962600B72D00A22755 /* UIImageView+Transition.h */; }; + 506BF6992600B72D00A22755 /* UIImageView+Transition.m in Sources */ = {isa = PBXBuildFile; fileRef = 506BF6972600B72D00A22755 /* UIImageView+Transition.m */; }; + 506BF7CE26067B0500A22755 /* AnimatedUIImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 506BF7CC26067B0500A22755 /* AnimatedUIImageView.h */; }; + 506BF7CF26067B0500A22755 /* AnimatedUIImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 506BF7CD26067B0500A22755 /* AnimatedUIImageView.m */; }; 506C2532244F0C6B00820F5B /* RotationTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 506C2530244F0C6B00820F5B /* RotationTransition.h */; }; 506C2533244F0C6B00820F5B /* RotationTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 506C2531244F0C6B00820F5B /* RotationTransition.m */; }; 506F630D216A599300AD0D0A /* RNNTabBarControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 506F630C216A599300AD0D0A /* RNNTabBarControllerTest.m */; }; @@ -305,8 +313,8 @@ 50B92C27253DDC6D0056FC26 /* ViewAnimationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50B92C25253DDC6D0056FC26 /* ViewAnimationOptions.m */; }; 50BAFE4B2399405800798674 /* RNNExternalViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 50BAFE492399405800798674 /* RNNExternalViewController.h */; }; 50BAFE4C2399405800798674 /* RNNExternalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50BAFE4A2399405800798674 /* RNNExternalViewController.m */; }; - 50BCB27123F1650800D6C8E5 /* SharedElementAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 50BCB26F23F1650800D6C8E5 /* SharedElementAnimator.h */; }; - 50BCB27223F1650800D6C8E5 /* SharedElementAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 50BCB27023F1650800D6C8E5 /* SharedElementAnimator.m */; }; + 50BCB27123F1650800D6C8E5 /* SharedElementTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 50BCB26F23F1650800D6C8E5 /* SharedElementTransition.h */; }; + 50BCB27223F1650800D6C8E5 /* SharedElementTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 50BCB27023F1650800D6C8E5 /* SharedElementTransition.m */; }; 50BCB27923F29F8D00D6C8E5 /* ElementFrameTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 50BCB27723F29F8D00D6C8E5 /* ElementFrameTransition.h */; }; 50BCB27A23F29F8D00D6C8E5 /* ElementFrameTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 50BCB27823F29F8D00D6C8E5 /* ElementFrameTransition.m */; }; 50BCB27D23F2A1EE00D6C8E5 /* FloatTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 50BCB27B23F2A1EE00D6C8E5 /* FloatTransition.h */; }; @@ -345,8 +353,8 @@ 50CF233A2405668C0098042D /* UINavigationController+RNNCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = 50CF23382405668C0098042D /* UINavigationController+RNNCommands.m */; }; 50D031342005149000386B3D /* RNNOverlayManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D031322005149000386B3D /* RNNOverlayManager.h */; }; 50D031352005149000386B3D /* RNNOverlayManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 50D031332005149000386B3D /* RNNOverlayManager.m */; }; - 50D3A36E23B8D6C600717F95 /* SharedElementTransitionsCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D3A36C23B8D6C600717F95 /* SharedElementTransitionsCreator.h */; }; - 50D3A36F23B8D6C600717F95 /* SharedElementTransitionsCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 50D3A36D23B8D6C600717F95 /* SharedElementTransitionsCreator.m */; }; + 50D3A36E23B8D6C600717F95 /* SharedElementAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D3A36C23B8D6C600717F95 /* SharedElementAnimator.h */; }; + 50D3A36F23B8D6C600717F95 /* SharedElementAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 50D3A36D23B8D6C600717F95 /* SharedElementAnimator.m */; }; 50D3A37223B8D77C00717F95 /* SharedElementTransitionOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D3A37023B8D77C00717F95 /* SharedElementTransitionOptions.h */; }; 50D3A37323B8D77C00717F95 /* SharedElementTransitionOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50D3A37123B8D77C00717F95 /* SharedElementTransitionOptions.m */; }; 50D3A37623BB5CD900717F95 /* OptionsArrayParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D3A37423BB5CD900717F95 /* OptionsArrayParser.h */; }; @@ -386,6 +394,10 @@ 50F5DFC21F407A8C001A00BC /* RNNBottomTabsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50F5DFC01F407A8C001A00BC /* RNNBottomTabsController.m */; }; 50F5DFC51F407AA0001A00BC /* RNNStackController.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F5DFC31F407AA0001A00BC /* RNNStackController.h */; }; 50F5DFC61F407AA0001A00BC /* RNNStackController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50F5DFC41F407AA0001A00BC /* RNNStackController.m */; }; + 50F72E1F260745DF0096758A /* TransformRectTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F72E1D260745DF0096758A /* TransformRectTransition.h */; }; + 50F72E20260745DF0096758A /* TransformRectTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 50F72E1E260745DF0096758A /* TransformRectTransition.m */; }; + 50F72E552607468C0096758A /* PathTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F72E532607468C0096758A /* PathTransition.h */; }; + 50F72E562607468C0096758A /* PathTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 50F72E542607468C0096758A /* PathTransition.m */; }; 50FCD83723FC102200000DD0 /* DeprecationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCD83523FC102200000DD0 /* DeprecationOptions.h */; }; 50FCD83823FC102200000DD0 /* DeprecationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50FCD83623FC102200000DD0 /* DeprecationOptions.m */; }; 651E1F8A21FD624600DFEA19 /* UISplitViewController+RNNOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 651E1F8921FD624600DFEA19 /* UISplitViewController+RNNOptions.m */; }; @@ -758,6 +770,14 @@ 50644A1F20E11A720026709C /* Constants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Constants.m; sourceTree = ""; }; 506A2B1220973DFD00F43A95 /* RNNErrorHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNErrorHandler.h; sourceTree = ""; }; 506A2B1320973DFD00F43A95 /* RNNErrorHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNErrorHandler.m; sourceTree = ""; }; + 506BF65A2600AE4200A22755 /* CenterTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CenterTransition.h; sourceTree = ""; }; + 506BF65B2600AE4200A22755 /* CenterTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CenterTransition.m; sourceTree = ""; }; + 506BF6602600AE7600A22755 /* BoundsTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BoundsTransition.h; sourceTree = ""; }; + 506BF6612600AE7600A22755 /* BoundsTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BoundsTransition.m; sourceTree = ""; }; + 506BF6962600B72D00A22755 /* UIImageView+Transition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIImageView+Transition.h"; sourceTree = ""; }; + 506BF6972600B72D00A22755 /* UIImageView+Transition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+Transition.m"; sourceTree = ""; }; + 506BF7CC26067B0500A22755 /* AnimatedUIImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnimatedUIImageView.h; sourceTree = ""; }; + 506BF7CD26067B0500A22755 /* AnimatedUIImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AnimatedUIImageView.m; sourceTree = ""; }; 506C2530244F0C6B00820F5B /* RotationTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RotationTransition.h; sourceTree = ""; }; 506C2531244F0C6B00820F5B /* RotationTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RotationTransition.m; sourceTree = ""; }; 506F630C216A599300AD0D0A /* RNNTabBarControllerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTabBarControllerTest.m; sourceTree = ""; }; @@ -827,8 +847,8 @@ 50B92C25253DDC6D0056FC26 /* ViewAnimationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewAnimationOptions.m; sourceTree = ""; }; 50BAFE492399405800798674 /* RNNExternalViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNExternalViewController.h; sourceTree = ""; }; 50BAFE4A2399405800798674 /* RNNExternalViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNExternalViewController.m; sourceTree = ""; }; - 50BCB26F23F1650800D6C8E5 /* SharedElementAnimator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharedElementAnimator.h; sourceTree = ""; }; - 50BCB27023F1650800D6C8E5 /* SharedElementAnimator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SharedElementAnimator.m; sourceTree = ""; }; + 50BCB26F23F1650800D6C8E5 /* SharedElementTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharedElementTransition.h; sourceTree = ""; }; + 50BCB27023F1650800D6C8E5 /* SharedElementTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SharedElementTransition.m; sourceTree = ""; }; 50BCB27723F29F8D00D6C8E5 /* ElementFrameTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ElementFrameTransition.h; sourceTree = ""; }; 50BCB27823F29F8D00D6C8E5 /* ElementFrameTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ElementFrameTransition.m; sourceTree = ""; }; 50BCB27B23F2A1EE00D6C8E5 /* FloatTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FloatTransition.h; sourceTree = ""; }; @@ -866,8 +886,8 @@ 50CF23382405668C0098042D /* UINavigationController+RNNCommands.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UINavigationController+RNNCommands.m"; sourceTree = ""; }; 50D031322005149000386B3D /* RNNOverlayManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNOverlayManager.h; sourceTree = ""; }; 50D031332005149000386B3D /* RNNOverlayManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNOverlayManager.m; sourceTree = ""; }; - 50D3A36C23B8D6C600717F95 /* SharedElementTransitionsCreator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharedElementTransitionsCreator.h; sourceTree = ""; }; - 50D3A36D23B8D6C600717F95 /* SharedElementTransitionsCreator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SharedElementTransitionsCreator.m; sourceTree = ""; }; + 50D3A36C23B8D6C600717F95 /* SharedElementAnimator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharedElementAnimator.h; sourceTree = ""; }; + 50D3A36D23B8D6C600717F95 /* SharedElementAnimator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SharedElementAnimator.m; sourceTree = ""; }; 50D3A37023B8D77C00717F95 /* SharedElementTransitionOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharedElementTransitionOptions.h; sourceTree = ""; }; 50D3A37123B8D77C00717F95 /* SharedElementTransitionOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SharedElementTransitionOptions.m; sourceTree = ""; }; 50D3A37423BB5CD900717F95 /* OptionsArrayParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OptionsArrayParser.h; sourceTree = ""; }; @@ -910,6 +930,10 @@ 50F5DFC01F407A8C001A00BC /* RNNBottomTabsController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNBottomTabsController.m; sourceTree = ""; }; 50F5DFC31F407AA0001A00BC /* RNNStackController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNStackController.h; sourceTree = ""; }; 50F5DFC41F407AA0001A00BC /* RNNStackController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNStackController.m; sourceTree = ""; }; + 50F72E1D260745DF0096758A /* TransformRectTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TransformRectTransition.h; sourceTree = ""; }; + 50F72E1E260745DF0096758A /* TransformRectTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TransformRectTransition.m; sourceTree = ""; }; + 50F72E532607468C0096758A /* PathTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PathTransition.h; sourceTree = ""; }; + 50F72E542607468C0096758A /* PathTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PathTransition.m; sourceTree = ""; }; 50FCD83523FC102200000DD0 /* DeprecationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeprecationOptions.h; sourceTree = ""; }; 50FCD83623FC102200000DD0 /* DeprecationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeprecationOptions.m; sourceTree = ""; }; 651E1F8821FD611600DFEA19 /* UISplitViewController+RNNOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UISplitViewController+RNNOptions.h"; sourceTree = ""; }; @@ -1090,6 +1114,8 @@ 7365071021E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.m */, 5030B62823D5C9AF008F1642 /* RCTConvert+Interpolation.h */, 9F8E06B424EBDB48004BDA83 /* RCTConvert+Interpolation.m */, + 506BF6962600B72D00A22755 /* UIImageView+Transition.h */, + 506BF6972600B72D00A22755 /* UIImageView+Transition.m */, 5095BB702416A3B900C4CD41 /* RNNConvert.h */, 5095BB712416A3B900C4CD41 /* RNNConvert.m */, 5038A3BB216E1490009280BC /* RNNTabBarItemCreator.h */, @@ -1376,8 +1402,16 @@ B8B2BB6424FFCC9500FC6575 /* CornerRadiusTransition.m */, 50B92C24253DDC6D0056FC26 /* ViewAnimationOptions.h */, 50B92C25253DDC6D0056FC26 /* ViewAnimationOptions.m */, - 50E38DDC23A7A306009817F6 /* AnimatedImageView.m */, + 50F72E532607468C0096758A /* PathTransition.h */, + 50F72E542607468C0096758A /* PathTransition.m */, + 506BF65A2600AE4200A22755 /* CenterTransition.h */, + 506BF65B2600AE4200A22755 /* CenterTransition.m */, + 506BF6602600AE7600A22755 /* BoundsTransition.h */, + 506BF6612600AE7600A22755 /* BoundsTransition.m */, 50E38DDB23A7A306009817F6 /* AnimatedImageView.h */, + 50E38DDC23A7A306009817F6 /* AnimatedImageView.m */, + 506BF7CC26067B0500A22755 /* AnimatedUIImageView.h */, + 506BF7CD26067B0500A22755 /* AnimatedUIImageView.m */, 50EA541823AEE1C6006F881A /* AnimatedReactView.h */, 50EA541923AEE1C6006F881A /* AnimatedReactView.m */, 50EAF67D23A7B9260006A86D /* AnimatedTextView.h */, @@ -1436,14 +1470,16 @@ 50588B8A23AAC2FF001F6A5E /* DisplayLinkAnimation.h */, 50EA541423AEDF5D006F881A /* RNNInterpolator.h */, 50EA541523AEDF5D006F881A /* RNNInterpolator.m */, - 50D3A36C23B8D6C600717F95 /* SharedElementTransitionsCreator.h */, - 50D3A36D23B8D6C600717F95 /* SharedElementTransitionsCreator.m */, + 50D3A36C23B8D6C600717F95 /* SharedElementAnimator.h */, + 50D3A36D23B8D6C600717F95 /* SharedElementAnimator.m */, 503A8A2323BD04410094D1C4 /* ElementTransitionsCreator.h */, 503A8A2423BD04410094D1C4 /* ElementTransitionsCreator.m */, 503A89FF23BB7B810094D1C4 /* ElementAnimator.h */, 503A8A0023BB7B810094D1C4 /* ElementAnimator.m */, - 50BCB26F23F1650800D6C8E5 /* SharedElementAnimator.h */, - 50BCB27023F1650800D6C8E5 /* SharedElementAnimator.m */, + 50BCB26F23F1650800D6C8E5 /* SharedElementTransition.h */, + 50BCB27023F1650800D6C8E5 /* SharedElementTransition.m */, + 50F72E1D260745DF0096758A /* TransformRectTransition.h */, + 50F72E1E260745DF0096758A /* TransformRectTransition.m */, 504189552506144D004A6BC7 /* RNNSetRootAnimator.h */, 504189562506144D004A6BC7 /* RNNSetRootAnimator.m */, 50D4656B23CE2553005A84B2 /* Transition.h */, @@ -1794,8 +1830,10 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 506BF6622600AE7600A22755 /* BoundsTransition.h in Headers */, 91CB34C9250ED50C000C132B /* RNNSearchBarOptions.h in Headers */, 5060DE73219DAD7E00D0C052 /* ReactNativeNavigation.h in Headers */, + 506BF7CE26067B0500A22755 /* AnimatedUIImageView.h in Headers */, 5022EDBD2405237100852BA6 /* BottomTabPresenterCreator.h in Headers */, 507ACB1523F44E5200829911 /* RNNComponentRootView.h in Headers */, 5061B6C723D48449008B9827 /* VerticalRotationTransition.h in Headers */, @@ -1904,7 +1942,9 @@ 50AB0B1C2255F8640039DAED /* UIViewController+LayoutProtocol.h in Headers */, 50D031342005149000386B3D /* RNNOverlayManager.h in Headers */, 50E5F7952240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h in Headers */, + 50F72E552607468C0096758A /* PathTransition.h in Headers */, 7B1126A71E2D2B6C00F9B03B /* RNNEventEmitter.h in Headers */, + 506BF6982600B72D00A22755 /* UIImageView+Transition.h in Headers */, E8A430111F9CB87B00B61A20 /* ElementAlphaTransition.h in Headers */, 5017D9E1239D2C6C00B74047 /* BottomTabsAttachModeFactory.h in Headers */, E5F6C3AC22DB4D0F0093C2CE /* UITabBarController+RNNUtils.h in Headers */, @@ -1923,6 +1963,7 @@ 503A90BD25DD550600BB6A74 /* RNNIconDrawer.h in Headers */, E8AEDB3C1F55A1C2000F5A6A /* RNNElementView.h in Headers */, E8E518321F83B3E0000467AC /* RNNUtils.h in Headers */, + 50F72E1F260745DF0096758A /* TransformRectTransition.h in Headers */, 50E5F791223FA04C002AFEAD /* TransitionDetailsOptions.h in Headers */, 50D4656D23CE2553005A84B2 /* Transition.h in Headers */, 5049594E216F6277006D2B81 /* NumberParser.h in Headers */, @@ -1962,6 +2003,7 @@ 5022EDC124053C9F00852BA6 /* TabBarItemAppearanceCreator.h in Headers */, 50395593217485B000B0A663 /* Double.h in Headers */, 5050465421F8F4490035497A /* RNNReactComponentRegistry.h in Headers */, + 506BF65C2600AE4200A22755 /* CenterTransition.h in Headers */, 504AFE741FFFF0540076E904 /* RNNTopTabsOptions.h in Headers */, 50E38DD723A7A2BE009817F6 /* AnimatedViewFactory.h in Headers */, E8E5182E1F83A48B000467AC /* RNNTransitionStateHolder.h in Headers */, @@ -1989,7 +2031,7 @@ 50175CD1207A2AA1004FE91B /* RNNComponentOptions.h in Headers */, 5038A3B1216DF41B009280BC /* UIViewController+RNNOptions.h in Headers */, 5049595A216F6B46006D2B81 /* NullDictionary.h in Headers */, - 50BCB27123F1650800D6C8E5 /* SharedElementAnimator.h in Headers */, + 50BCB27123F1650800D6C8E5 /* SharedElementTransition.h in Headers */, 50B92C26253DDC6D0056FC26 /* ViewAnimationOptions.h in Headers */, 50BCB27D23F2A1EE00D6C8E5 /* FloatTransition.h in Headers */, 501224062173592D000F5F98 /* RNNBottomTabsPresenter.h in Headers */, @@ -2003,7 +2045,7 @@ 30987CA5048A48D6CE76B06C /* DotIndicatorParser.h in Headers */, 3098730BC3B4DE41104D9CC4 /* RNNDotIndicatorPresenter.h in Headers */, 5095BB722416A3B900C4CD41 /* RNNConvert.h in Headers */, - 50D3A36E23B8D6C600717F95 /* SharedElementTransitionsCreator.h in Headers */, + 50D3A36E23B8D6C600717F95 /* SharedElementAnimator.h in Headers */, 309877F473AECC05FB3B9362 /* UITabBarController+RNNUtils.h in Headers */, 3098702E6833E5CC16D91CE3 /* NoColor.h in Headers */, 5017D9EA239D2F9D00B74047 /* BottomTabsTogetherAttacher.h in Headers */, @@ -2146,6 +2188,7 @@ 50C4A497206BDDBB00DB292E /* RNNSubtitleOptions.m in Sources */, 509416A823A11C630036092C /* EnumParser.m in Sources */, 50AB0B1D2255F8640039DAED /* UIViewController+LayoutProtocol.m in Sources */, + 50F72E20260745DF0096758A /* TransformRectTransition.m in Sources */, 263905B41E4C6F440023D7D3 /* MMDrawerVisualState.m in Sources */, 5012240B21735959000F5F98 /* RNNSideMenuPresenter.m in Sources */, 502CB46F20CD1DDA0019B2FE /* RNNBackButtonOptions.m in Sources */, @@ -2157,6 +2200,7 @@ 503A8FEE25DD397400BB6A74 /* RNNIconCreator.m in Sources */, 50DE2E46238EA14E005CD5F4 /* NSArray+utils.m in Sources */, 50495943216F5E5D006D2B81 /* NullBool.m in Sources */, + 506BF65D2600AE4200A22755 /* CenterTransition.m in Sources */, 5022EDBE2405237100852BA6 /* BottomTabPresenterCreator.m in Sources */, 5038A3C7216E2D93009280BC /* Number.m in Sources */, E5F6C3A622DB4D0F0093C2CE /* UIViewController+Utils.m in Sources */, @@ -2185,7 +2229,7 @@ 50BE951220B5A787004F5DF5 /* RNNStatusBarOptions.m in Sources */, 50C085EC259143F200B0502C /* RNNButtonsParser.m in Sources */, 50495953216F62BD006D2B81 /* NullNumber.m in Sources */, - 50D3A36F23B8D6C600717F95 /* SharedElementTransitionsCreator.m in Sources */, + 50D3A36F23B8D6C600717F95 /* SharedElementAnimator.m in Sources */, 5012242721737278000F5F98 /* NullImage.m in Sources */, 5022EDC624054C6100852BA6 /* BottomTabsAppearancePresenter.m in Sources */, 7B1126A01E2D263F00F9B03B /* RNNEventEmitter.m in Sources */, @@ -2215,6 +2259,7 @@ 50E38DDE23A7A306009817F6 /* AnimatedImageView.m in Sources */, 263905B21E4C6F440023D7D3 /* MMDrawerController.m in Sources */, 50644A2120E11A720026709C /* Constants.m in Sources */, + 506BF6632600AE7600A22755 /* BoundsTransition.m in Sources */, 501223D82173590F000F5F98 /* RNNStackPresenter.m in Sources */, E8AEDB3D1F55A1C2000F5A6A /* RNNElementView.m in Sources */, E83BAD6B1F27363A00A9F3DD /* RNNNavigationOptions.m in Sources */, @@ -2236,6 +2281,7 @@ 5030B62223D5B4CB008F1642 /* Color+Interpolation.m in Sources */, 50395594217485B000B0A663 /* Double.m in Sources */, 504AFE751FFFF0540076E904 /* RNNTopTabsOptions.m in Sources */, + 506BF7CF26067B0500A22755 /* AnimatedUIImageView.m in Sources */, 50175CD2207A2AA1004FE91B /* RNNComponentOptions.m in Sources */, 505C640323E074860078AFC0 /* TopBarTitlePresenter.m in Sources */, 50EA541F23B00E03006F881A /* StackControllerDelegate.m in Sources */, @@ -2277,6 +2323,7 @@ 50D3A37723BB5CD900717F95 /* OptionsArrayParser.m in Sources */, 50AD288923CDB71C00FF3134 /* ElementHorizontalTransition.m in Sources */, E33AC20820B5C4F90090DB8A /* RNNSplitViewOptions.m in Sources */, + 506BF6992600B72D00A22755 /* UIImageView+Transition.m in Sources */, 50BCB28A23F2B4DE00D6C8E5 /* ColorTransition.m in Sources */, B8B2BB6624FFCC9500FC6575 /* CornerRadiusTransition.m in Sources */, E33AC20020B5BA0B0090DB8A /* RNNSplitViewController.m in Sources */, @@ -2294,6 +2341,7 @@ 507F43C61FF4F17C00D9425B /* RNNTopTabsViewController.m in Sources */, 50706E6E20CE7CA5003345C3 /* UIImage+utils.m in Sources */, 50CED452239F9DFC00C42EE2 /* TopBarPresenter.m in Sources */, + 50F72E562607468C0096758A /* PathTransition.m in Sources */, 50FCD83823FC102200000DD0 /* DeprecationOptions.m in Sources */, 50BCB29223F2C7CD00D6C8E5 /* AnchorTransition.m in Sources */, 50344D2923A03DB4004B6A7C /* BottomTabsAttachMode.m in Sources */, @@ -2305,7 +2353,7 @@ 5008641223856A2D00A55BE9 /* UITabBar+utils.m in Sources */, 9FDA2ABE24F2A42C005678CC /* RCTConvert+UIFontWeight.m in Sources */, 9FDA2AC024F2A43B005678CC /* RCTConvert+SideMenuOpenGestureMode.m in Sources */, - 50BCB27223F1650800D6C8E5 /* SharedElementAnimator.m in Sources */, + 50BCB27223F1650800D6C8E5 /* SharedElementTransition.m in Sources */, E5F6C3A822DB4D0F0093C2CE /* UIView+Utils.m in Sources */, 5049593F216F5D73006D2B81 /* BoolParser.m in Sources */, 50EB93421FE14A3E00BD8EEE /* RNNBottomTabOptions.m in Sources */, diff --git a/lib/ios/ScreenAnimationController.m b/lib/ios/ScreenAnimationController.m index 1a1513c2670..11e5cd39605 100644 --- a/lib/ios/ScreenAnimationController.m +++ b/lib/ios/ScreenAnimationController.m @@ -1,11 +1,13 @@ #import "ScreenAnimationController.h" #import "DisplayLinkAnimator.h" #import "RNNScreenTransitionsCreator.h" +#import "SharedElementAnimator.h" #import "UIViewController+LayoutProtocol.h" @implementation ScreenAnimationController { RCTBridge *_bridge; id _transitionContext; + SharedElementAnimator *_sharedElementAnimator; BOOL _animate; CGFloat _duration; } @@ -46,19 +48,24 @@ - (void)prepareTransitionContext:(id)trans [transitionContext.containerView addSubview:fromView]; [transitionContext.containerView addSubview:toViewController.view]; - [[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey] - prepareForTransition]; + [toViewController prepareForTransition]; } - (NSArray *)createTransitionsFromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC containerView:(UIView *)containerView { - return [RNNScreenTransitionsCreator createTransitionsFromVC:fromVC - toVC:toVC - containerView:containerView - contentTransition:self.content - elementTransitions:self.elementTransitions - sharedElementTransitions:self.sharedElementTransitions]; + NSArray *transitions = + [RNNScreenTransitionsCreator createTransitionsFromVC:fromVC + toVC:toVC + containerView:containerView + contentTransition:self.content + elementTransitions:self.elementTransitions]; + _sharedElementAnimator = + [[SharedElementAnimator alloc] initWithTransitions:self.sharedElementTransitions + fromVC:fromVC + toVC:toVC + containerView:containerView]; + return [transitions arrayByAddingObjectsFromArray:[_sharedElementAnimator create]]; } - (void)performAnimationOnce { @@ -70,7 +77,6 @@ - (void)performAnimationOnce { [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; - NSArray *transitions = [self createTransitionsFromVC:fromVC toVC:toVC containerView:transitionContext.containerView]; @@ -122,10 +128,12 @@ - (void)uiManagerDidPerformMounting:(RCTUIManager *)manager { - (void)animationEnded:(BOOL)transitionCompleted { UIView *toView = [_transitionContext viewForKey:UITransitionContextToViewKey]; UIView *fromView = [_transitionContext viewForKey:UITransitionContextFromViewKey]; + [_sharedElementAnimator animationEnded]; toView.layer.transform = CATransform3DIdentity; fromView.layer.transform = CATransform3DIdentity; toView.alpha = 1.f; _transitionContext = nil; + _sharedElementAnimator = nil; } @end diff --git a/lib/ios/SharedElementAnimator.h b/lib/ios/SharedElementAnimator.h index 8988e755dc9..92a580f2ea6 100644 --- a/lib/ios/SharedElementAnimator.h +++ b/lib/ios/SharedElementAnimator.h @@ -1,18 +1,17 @@ #import "AnimatedReactView.h" -#import "BaseAnimator.h" -#import "ElementAnimator.h" -#import "SharedElementTransitionOptions.h" +#import "DisplayLinkAnimatorDelegate.h" #import -@interface SharedElementAnimator : ElementAnimator +@interface SharedElementAnimator : NSObject -- (instancetype)initWithTransitionOptions:(SharedElementTransitionOptions *)transitionOptions - fromView:(UIView *)fromView - toView:(UIView *)toView - fromVC:(UIViewController *)fromVC - toVC:(UIViewController *)toVC - containerView:(UIView *)containerView; +- (instancetype)initWithTransitions: + (NSArray *)sharedElementTransitions + fromVC:(UIViewController *)fromVC + toVC:(UIViewController *)toVC + containerView:(UIView *)containerView; -@property(nonatomic, strong) AnimatedReactView *view; +- (NSArray *)create; + +- (void)animationEnded; @end diff --git a/lib/ios/SharedElementAnimator.m b/lib/ios/SharedElementAnimator.m index 467b872a33d..beceff0fe66 100644 --- a/lib/ios/SharedElementAnimator.m +++ b/lib/ios/SharedElementAnimator.m @@ -1,104 +1,83 @@ #import "SharedElementAnimator.h" -#import "AnchorTransition.h" -#import "AnimatedTextView.h" #import "AnimatedViewFactory.h" -#import "ColorTransition.h" -#import "CornerRadiusTransition.h" -#import "RectTransition.h" -#import "RotationTransition.h" -#import "TextStorageTransition.h" +#import "BaseAnimator.h" +#import "NSArray+utils.h" +#import "RNNElementFinder.h" +#import "SharedElementTransition.h" +#import "UIViewController+LayoutProtocol.h" @implementation SharedElementAnimator { - SharedElementTransitionOptions *_transitionOptions; - UIViewController *_toVC; + NSArray *_sharedElementTransitions; + NSArray *_transitions; UIViewController *_fromVC; - UIView *_fromView; - UIView *_toView; + UIViewController *_toVC; UIView *_containerView; } -- (instancetype)initWithTransitionOptions:(SharedElementTransitionOptions *)transitionOptions - fromView:(UIView *)fromView - toView:(UIView *)toView - fromVC:(UIViewController *)fromVC - toVC:(UIViewController *)toVC - containerView:(UIView *)containerView { +- (instancetype)initWithTransitions: + (NSArray *)sharedElementTransitions + fromVC:(UIViewController *)fromVC + toVC:(UIViewController *)toVC + containerView:(UIView *)containerView { self = [super init]; - _transitionOptions = transitionOptions; + _sharedElementTransitions = sharedElementTransitions; _fromVC = fromVC; _toVC = toVC; - _fromView = fromView; - _toView = toView; _containerView = containerView; - self.view = [self createAnimatedView:transitionOptions fromView:fromView toView:toView]; - self.animations = [self createAnimations]; - return self; -} -- (AnimatedReactView *)createAnimatedView:(SharedElementTransitionOptions *)transitionOptions - fromView:(UIView *)fromView - toView:(UIView *)toView { - return [AnimatedViewFactory createFromElement:fromView - toElement:toView - transitionOptions:transitionOptions]; + return self; } -- (NSMutableArray> *)createAnimations { - NSMutableArray *animations = [super createAnimations:_transitionOptions]; - CGFloat startDelay = [_transitionOptions.startDelay withDefault:0]; - CGFloat duration = [_transitionOptions.duration withDefault:300]; - id interpolator = _transitionOptions.interpolator; +- (NSArray *)create { + NSMutableArray *transitions = + [NSMutableArray new]; + for (SharedElementTransitionOptions *transitionOptions in _sharedElementTransitions) { + UIView *fromView = + [RNNElementFinder findElementForId:transitionOptions.fromId + inView:_fromVC.presentedComponentViewController.reactView]; + UIView *toView = + [RNNElementFinder findElementForId:transitionOptions.toId + inView:_toVC.presentedComponentViewController.reactView]; + if (fromView == nil || toView == nil) { + break; + } - if (!CGRectEqualToRect(self.view.location.fromFrame, self.view.location.toFrame)) { - [animations addObject:[[RectTransition alloc] initWithView:self.view - from:self.view.location.fromFrame - to:self.view.location.toFrame - startDelay:startDelay - duration:duration - interpolator:interpolator]]; + SharedElementTransition *sharedElementAnimator = + [[SharedElementTransition alloc] initWithTransitionOptions:transitionOptions + fromView:fromView + toView:toView + containerView:_containerView]; + [transitions addObject:sharedElementAnimator]; } - if (![_fromView.backgroundColor isEqual:_toView.backgroundColor]) { - [animations addObject:[[ColorTransition alloc] initWithView:self.view - from:_fromView.backgroundColor - to:_toView.backgroundColor - startDelay:startDelay - duration:duration - interpolator:interpolator]]; - } + NSArray *sortedTransitions = [self sortByZIndex:transitions]; + [self addSharedElementViews:sortedTransitions toContainerView:_containerView]; + _transitions = transitions; - if ([self.view isKindOfClass:AnimatedTextView.class]) { - [animations addObject:[[TextStorageTransition alloc] - initWithView:self.view - from:((AnimatedTextView *)self.view).fromTextStorage - to:((AnimatedTextView *)self.view).toTextStorage - startDelay:startDelay - duration:duration - interpolator:interpolator]]; - } + return sortedTransitions; +} - if (self.view.location.fromCornerRadius != self.view.location.toCornerRadius) { - // TODO: Use MaskedCorners to only round specific corners, e.g.: - // borderTopLeftRadius - // self.view.layer.maskedCorners = kCALayerMinXMinYCorner | - // kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | - // kCALayerMaxXMaxYCorner; - self.view.layer.masksToBounds = YES; - [animations addObject:[[CornerRadiusTransition alloc] - initWithView:self.view - fromFloat:self.view.location.fromCornerRadius - toFloat:self.view.location.toCornerRadius - startDelay:startDelay - duration:duration - interpolator:interpolator]]; +- (void)animationEnded { + for (SharedElementTransition *transition in _transitions.reverseObjectEnumerator) { + [transition.view reset]; } +} - return animations; +- (void)addSharedElementViews:(NSArray *)animators + toContainerView:(UIView *)containerView { + for (BaseAnimator *animator in animators) { + [containerView addSubview:animator.view]; + } } -- (void)end { - [super end]; - [self.view reset]; +- (NSArray *)sortByZIndex: + (NSArray *)animators { + return (NSArray *)[animators + sortedArrayUsingComparator:^NSComparisonResult(BaseAnimator *a, BaseAnimator *b) { + id first = [a.view valueForKey:@"reactZIndex"]; + id second = [b.view valueForKey:@"reactZIndex"]; + return [first compare:second]; + }]; } @end diff --git a/lib/ios/SharedElementTransition.h b/lib/ios/SharedElementTransition.h new file mode 100644 index 00000000000..3b165a05686 --- /dev/null +++ b/lib/ios/SharedElementTransition.h @@ -0,0 +1,17 @@ +#import "AnimatedReactView.h" +#import "BaseAnimator.h" +#import "ElementAnimator.h" +#import "SharedElementTransitionOptions.h" +#import + +@interface SharedElementTransition : ElementAnimator + +- (instancetype)initWithTransitionOptions:(SharedElementTransitionOptions *)transitionOptions + fromView:(UIView *)fromView + toView:(UIView *)toView + containerView:(UIView *)containerView; + +@property(nonatomic, strong) AnimatedReactView *view; +@property(nonatomic, strong) UIView *parentView; + +@end diff --git a/lib/ios/SharedElementTransition.m b/lib/ios/SharedElementTransition.m new file mode 100644 index 00000000000..ea2260d9145 --- /dev/null +++ b/lib/ios/SharedElementTransition.m @@ -0,0 +1,133 @@ +#import "SharedElementTransition.h" +#import "AnchorTransition.h" +#import "AnimatedTextView.h" +#import "AnimatedViewFactory.h" +#import "BoundsTransition.h" +#import "CenterTransition.h" +#import "ColorTransition.h" +#import "CornerRadiusTransition.h" +#import "PathTransition.h" +#import "RectTransition.h" +#import "RotationTransition.h" +#import "TextStorageTransition.h" +#import "TransformRectTransition.h" +#import "UIImageView+Transition.h" + +@implementation SharedElementTransition { + SharedElementTransitionOptions *_transitionOptions; + UIView *_fromView; + UIView *_toView; + UIView *_containerView; +} + +- (instancetype)initWithTransitionOptions:(SharedElementTransitionOptions *)transitionOptions + fromView:(UIView *)fromView + toView:(UIView *)toView + containerView:(UIView *)containerView { + self = [super init]; + _transitionOptions = transitionOptions; + _fromView = fromView; + _toView = toView; + _containerView = containerView; + self.view = [self createAnimatedView:transitionOptions fromView:fromView toView:toView]; + _parentView = self.view.superview; + self.animations = [self createAnimations]; + return self; +} + +- (AnimatedReactView *)createAnimatedView:(SharedElementTransitionOptions *)transitionOptions + fromView:(UIView *)fromView + toView:(UIView *)toView { + return [AnimatedViewFactory createFromElement:fromView + toElement:toView + transitionOptions:transitionOptions]; +} + +- (NSMutableArray> *)createAnimations { + NSMutableArray *animations = [super createAnimations:_transitionOptions]; + CGFloat startDelay = [_transitionOptions.startDelay withDefault:0]; + CGFloat duration = [_transitionOptions.duration withDefault:300]; + id interpolator = _transitionOptions.interpolator; + + if (!CGRectEqualToRect(self.view.location.fromBounds, self.view.location.toBounds)) { + [animations addObject:[[BoundsTransition alloc] initWithView:self.view + from:self.view.location.fromBounds + to:self.view.location.toBounds + startDelay:startDelay + duration:duration + interpolator:interpolator]]; + } + + if (!CGPointEqualToPoint(self.view.location.fromCenter, self.view.location.toCenter)) { + [animations addObject:[[CenterTransition alloc] initWithView:self.view + from:self.view.location.fromCenter + to:self.view.location.toCenter + startDelay:startDelay + duration:duration + interpolator:interpolator]]; + } + + if (![_fromView.backgroundColor isEqual:_toView.backgroundColor]) { + [animations addObject:[[ColorTransition alloc] initWithView:self.view + from:_fromView.backgroundColor + to:_toView.backgroundColor + startDelay:startDelay + duration:duration + interpolator:interpolator]]; + } + + if ([self.view isKindOfClass:AnimatedTextView.class]) { + [animations addObject:[[TextStorageTransition alloc] + initWithView:self.view + from:((AnimatedTextView *)self.view).fromTextStorage + to:((AnimatedTextView *)self.view).toTextStorage + startDelay:startDelay + duration:duration + interpolator:interpolator]]; + } + + if (!CGRectEqualToRect(self.view.location.fromPath, self.view.location.toPath)) { + [animations + addObject:[[PathTransition alloc] initWithView:self.view + fromPath:self.view.location.fromPath + toPath:self.view.location.toPath + fromCornerRadius:self.view.location.fromCornerRadius + toCornerRadius:self.view.location.toCornerRadius + startDelay:startDelay + duration:duration + interpolator:interpolator]]; + } + + if (!CATransform3DEqualToTransform(self.view.location.fromTransform, + self.view.location.toTransform)) { + [animations + addObject:[[TransformRectTransition alloc] initWithView:self.view + from:self.view.location.fromTransform + to:self.view.location.toTransform + startDelay:startDelay + duration:duration + interpolator:interpolator]]; + } + + if (self.view.location.fromCornerRadius != self.view.location.toCornerRadius) { + // TODO: Use MaskedCorners to only round specific corners, e.g.: + // borderTopLeftRadius + // self.view.layer.maskedCorners = kCALayerMinXMinYCorner | + // kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | + // kCALayerMaxXMaxYCorner; + self.view.layer.masksToBounds = YES; + [animations addObject:[[CornerRadiusTransition alloc] + initWithView:self.view + fromFloat:self.view.location.fromCornerRadius + toFloat:self.view.location.toCornerRadius + startDelay:startDelay + duration:duration + interpolator:interpolator]]; + } + + [animations addObjectsFromArray:self.view.extraAnimations]; + + return animations; +} + +@end diff --git a/lib/ios/SharedElementTransitionsCreator.h b/lib/ios/SharedElementTransitionsCreator.h deleted file mode 100644 index 17da2725faa..00000000000 --- a/lib/ios/SharedElementTransitionsCreator.h +++ /dev/null @@ -1,13 +0,0 @@ -#import "AnimatedReactView.h" -#import "DisplayLinkAnimatorDelegate.h" -#import - -@interface SharedElementTransitionsCreator : NSObject - -+ (NSArray *) - create:(NSArray *)sharedElementTransitions - fromVC:(UIViewController *)fromVC - toVC:(UIViewController *)toVC - containerView:(UIView *)containerView; - -@end diff --git a/lib/ios/SharedElementTransitionsCreator.m b/lib/ios/SharedElementTransitionsCreator.m deleted file mode 100644 index b00379019db..00000000000 --- a/lib/ios/SharedElementTransitionsCreator.m +++ /dev/null @@ -1,62 +0,0 @@ -#import "SharedElementTransitionsCreator.h" -#import "AnimatedViewFactory.h" -#import "BaseAnimator.h" -#import "NSArray+utils.h" -#import "RNNElementFinder.h" -#import "SharedElementAnimator.h" -#import "UIViewController+LayoutProtocol.h" - -@implementation SharedElementTransitionsCreator - -+ (NSArray *) - create:(NSArray *)sharedElementTransitions - fromVC:(UIViewController *)fromVC - toVC:(UIViewController *)toVC - containerView:(UIView *)containerView { - NSMutableArray *transitions = - [NSMutableArray new]; - for (SharedElementTransitionOptions *transitionOptions in sharedElementTransitions) { - UIView *fromView = - [RNNElementFinder findElementForId:transitionOptions.fromId - inView:fromVC.presentedComponentViewController.reactView]; - UIView *toView = - [RNNElementFinder findElementForId:transitionOptions.toId - inView:toVC.presentedComponentViewController.reactView]; - if (fromView == nil || toView == nil) { - break; - } - - SharedElementAnimator *sharedElementAnimator = - [[SharedElementAnimator alloc] initWithTransitionOptions:transitionOptions - fromView:fromView - toView:toView - fromVC:fromVC - toVC:toVC - containerView:containerView]; - [transitions addObject:sharedElementAnimator]; - } - - NSArray *sortedTransitions = [self sortByZIndex:transitions]; - [self addSharedElementViews:sortedTransitions toContainerView:containerView]; - - return sortedTransitions; -} - -+ (void)addSharedElementViews:(NSArray *)animators - toContainerView:(UIView *)containerView { - for (BaseAnimator *animator in animators) { - [containerView addSubview:animator.view]; - } -} - -+ (NSArray *)sortByZIndex: - (NSArray *)animators { - return (NSArray *)[animators - sortedArrayUsingComparator:^NSComparisonResult(BaseAnimator *a, BaseAnimator *b) { - id first = [a.view valueForKey:@"reactZIndex"]; - id second = [b.view valueForKey:@"reactZIndex"]; - return [first compare:second]; - }]; -} - -@end diff --git a/lib/ios/TransformRectTransition.h b/lib/ios/TransformRectTransition.h new file mode 100644 index 00000000000..79cfa89b34f --- /dev/null +++ b/lib/ios/TransformRectTransition.h @@ -0,0 +1,12 @@ +#import "RectTransition.h" + +@interface TransformRectTransition : RectTransition + +- (instancetype)initWithView:(UIView *)view + from:(CATransform3D)from + to:(CATransform3D)to + startDelay:(NSTimeInterval)startDelay + duration:(NSTimeInterval)duration + interpolator:(id)interpolator; + +@end diff --git a/lib/ios/TransformRectTransition.m b/lib/ios/TransformRectTransition.m new file mode 100644 index 00000000000..c7c023b528e --- /dev/null +++ b/lib/ios/TransformRectTransition.m @@ -0,0 +1,31 @@ +#import "TransformRectTransition.h" + +@implementation TransformRectTransition { + CATransform3D _fromTransform; + CATransform3D _toTransform; +} + +- (instancetype)initWithView:(UIView *)view + from:(CATransform3D)from + to:(CATransform3D)to + startDelay:(NSTimeInterval)startDelay + duration:(NSTimeInterval)duration + interpolator:(id)interpolator { + self = [super initWithView:view + startDelay:startDelay + duration:duration + interpolator:interpolator]; + _fromTransform = from; + _toTransform = to; + return self; +} + +- (CATransform3D)animateWithProgress:(CGFloat)p { + CATransform3D toTransform = [RNNInterpolator fromTransform:_fromTransform + toTransform:_toTransform + precent:p + interpolator:self.interpolator]; + return toTransform; +} + +@end diff --git a/lib/ios/UIImageView+Transition.h b/lib/ios/UIImageView+Transition.h new file mode 100644 index 00000000000..8b1b2b24d6b --- /dev/null +++ b/lib/ios/UIImageView+Transition.h @@ -0,0 +1,7 @@ +#import + +@interface UIImageView (Transition) + +- (CGRect)resolveBounds; + +@end diff --git a/lib/ios/UIImageView+Transition.m b/lib/ios/UIImageView+Transition.m new file mode 100644 index 00000000000..2e783f238c5 --- /dev/null +++ b/lib/ios/UIImageView+Transition.m @@ -0,0 +1,46 @@ +#import "UIImageView+Transition.h" + +@implementation UIImageView (Transition) + +- (CGRect)resolveBounds { + switch (self.contentMode) { + case UIViewContentModeCenter: + return CGRectMake(0, 0, self.image.size.width, self.image.size.height); + break; + case UIViewContentModeScaleAspectFill: { + CGSize imageSize = CGSizeMake(self.image.size.width, self.image.size.height); + + CGFloat widthRatio = imageSize.width / self.superview.bounds.size.width; + CGFloat heightRatio = imageSize.height / self.superview.bounds.size.height; + + if (widthRatio > heightRatio) { + imageSize = CGSizeMake(imageSize.width / heightRatio, imageSize.height / heightRatio); + } else { + imageSize = CGSizeMake(imageSize.width / widthRatio, imageSize.height / widthRatio); + } + + return CGRectMake(0, 0, imageSize.width, imageSize.height); + } + case UIViewContentModeScaleAspectFit: { + CGSize imageSize = CGSizeMake(self.image.size.width / self.image.scale, + self.image.size.height / self.image.scale); + + CGFloat widthRatio = imageSize.width / self.superview.bounds.size.width; + CGFloat heightRatio = imageSize.height / self.superview.bounds.size.height; + + if (widthRatio > heightRatio) { + imageSize = CGSizeMake(imageSize.width / widthRatio, imageSize.height / widthRatio); + } else { + imageSize = CGSizeMake(imageSize.width / heightRatio, imageSize.height / heightRatio); + } + + return CGRectMake(0, 0, imageSize.width, imageSize.height); + } + default: + break; + } + + return self.bounds; +} + +@end diff --git a/lib/ios/Utils/UIView+Utils.h b/lib/ios/Utils/UIView+Utils.h index 2f33b77a3f6..8ee1be2b511 100644 --- a/lib/ios/Utils/UIView+Utils.h +++ b/lib/ios/Utils/UIView+Utils.h @@ -1,7 +1,12 @@ #import #import -typedef NS_ENUM(NSInteger, ViewType) { ViewTypeImage, ViewTypeText, ViewTypeOther }; +typedef NS_ENUM(NSInteger, ViewType) { + ViewTypeImage, + ViewTypeUIImage, + ViewTypeText, + ViewTypeOther +}; @interface UIView (Utils) diff --git a/lib/ios/Utils/UIView+Utils.m b/lib/ios/Utils/UIView+Utils.m index b82e532e5f6..44e00f3cded 100644 --- a/lib/ios/Utils/UIView+Utils.m +++ b/lib/ios/Utils/UIView+Utils.m @@ -17,6 +17,8 @@ - (ViewType)viewType { return ViewTypeImage; } else if ([self isKindOfClass:[RCTTextView class]]) { return ViewTypeText; + } else if ([self isKindOfClass:[UIImageView class]]) { + return ViewTypeUIImage; } return ViewTypeOther; diff --git a/playground/android/build.gradle b/playground/android/build.gradle index 49ffb942998..a310af4adf9 100644 --- a/playground/android/build.gradle +++ b/playground/android/build.gradle @@ -24,7 +24,6 @@ buildscript { allprojects { repositories { - jcenter() maven { url 'https://www.jitpack.io' } google() maven { @@ -35,5 +34,6 @@ allprojects { maven { url "$rootDir/../../node_modules/detox/Detox-android" } maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } maven { url "$rootDir/../../node_modules/jsc-android/dist" } + jcenter() } } diff --git a/playground/src/screens/imageGallery/ImageGalleryListScreen.tsx b/playground/src/screens/imageGallery/ImageGalleryListScreen.tsx index 5d238eca299..7184aeb8c20 100644 --- a/playground/src/screens/imageGallery/ImageGalleryListScreen.tsx +++ b/playground/src/screens/imageGallery/ImageGalleryListScreen.tsx @@ -46,6 +46,22 @@ export default class ImageGalleryListScreen extends NavigationComponent { }, ], }, + pop: { + content: { + alpha: { + from: 1, + to: 0, + duration: SHORT_DURATION, + }, + }, + sharedElementTransitions: [ + { + toId: `image-${key}`, + fromId: `image-${key}Dest`, + duration: LONG_DURATION, + }, + ], + }, }, }, },