123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- /*
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
- #import "RCTLayoutAnimation.h"
- #import "RCTConvert.h"
- @implementation RCTLayoutAnimation
- static UIViewAnimationCurve _currentKeyboardAnimationCurve;
- static UIViewAnimationOptions UIViewAnimationOptionsFromRCTAnimationType(RCTAnimationType type)
- {
- switch (type) {
- case RCTAnimationTypeLinear:
- return UIViewAnimationOptionCurveLinear;
- case RCTAnimationTypeEaseIn:
- return UIViewAnimationOptionCurveEaseIn;
- case RCTAnimationTypeEaseOut:
- return UIViewAnimationOptionCurveEaseOut;
- case RCTAnimationTypeEaseInEaseOut:
- return UIViewAnimationOptionCurveEaseInOut;
- case RCTAnimationTypeKeyboard:
- // http://stackoverflow.com/questions/18870447/how-to-use-the-default-ios7-uianimation-curve
- return (UIViewAnimationOptions)(_currentKeyboardAnimationCurve << 16);
- default:
- RCTLogError(@"Unsupported animation type %lld", (long long)type);
- return UIViewAnimationOptionCurveEaseInOut;
- }
- }
- // Use a custom initialization function rather than implementing `+initialize` so that we can control
- // when the initialization code runs. `+initialize` runs immediately before the first message is sent
- // to the class which may be too late for us. By this time, we may have missed some
- // `UIKeyboardWillChangeFrameNotification`s.
- + (void)initializeStatics
- {
- #if !TARGET_OS_TV
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(keyboardWillChangeFrame:)
- name:UIKeyboardWillChangeFrameNotification
- object:nil];
- });
- #endif
- }
- + (void)keyboardWillChangeFrame:(NSNotification *)notification
- {
- #if !TARGET_OS_TV
- NSDictionary *userInfo = notification.userInfo;
- _currentKeyboardAnimationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
- #endif
- }
- - (instancetype)initWithDuration:(NSTimeInterval)duration
- delay:(NSTimeInterval)delay
- property:(NSString *)property
- springDamping:(CGFloat)springDamping
- initialVelocity:(CGFloat)initialVelocity
- animationType:(RCTAnimationType)animationType
- {
- if (self = [super init]) {
- _duration = duration;
- _delay = delay;
- _property = property;
- _springDamping = springDamping;
- _initialVelocity = initialVelocity;
- _animationType = animationType;
- }
- return self;
- }
- - (instancetype)initWithDuration:(NSTimeInterval)duration config:(NSDictionary *)config
- {
- if (!config) {
- return nil;
- }
- if (self = [super init]) {
- _property = [RCTConvert NSString:config[@"property"]];
- _duration = [RCTConvert NSTimeInterval:config[@"duration"]] ?: duration;
- if (_duration > 0.0 && _duration < 0.01) {
- RCTLogError(@"RCTLayoutAnimationGroup expects timings to be in ms, not seconds.");
- _duration = _duration * 1000.0;
- }
- _delay = [RCTConvert NSTimeInterval:config[@"delay"]];
- if (_delay > 0.0 && _delay < 0.01) {
- RCTLogError(@"RCTLayoutAnimationGroup expects timings to be in ms, not seconds.");
- _delay = _delay * 1000.0;
- }
- _animationType = [RCTConvert RCTAnimationType:config[@"type"]];
- if (_animationType == RCTAnimationTypeSpring) {
- _springDamping = [RCTConvert CGFloat:config[@"springDamping"]];
- _initialVelocity = [RCTConvert CGFloat:config[@"initialVelocity"]];
- }
- }
- return self;
- }
- - (void)performAnimations:(void (^)(void))animations withCompletionBlock:(void (^)(BOOL completed))completionBlock
- {
- if (_animationType == RCTAnimationTypeSpring) {
- [UIView animateWithDuration:_duration
- delay:_delay
- usingSpringWithDamping:_springDamping
- initialSpringVelocity:_initialVelocity
- options:UIViewAnimationOptionBeginFromCurrentState
- animations:animations
- completion:completionBlock];
- } else {
- UIViewAnimationOptions options =
- UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionsFromRCTAnimationType(_animationType);
- [UIView animateWithDuration:_duration
- delay:_delay
- options:options
- animations:animations
- completion:completionBlock];
- }
- }
- - (BOOL)isEqual:(RCTLayoutAnimation *)animation
- {
- return _duration == animation.duration && _delay == animation.delay &&
- (_property == animation.property || [_property isEqualToString:animation.property]) &&
- _springDamping == animation.springDamping && _initialVelocity == animation.initialVelocity &&
- _animationType == animation.animationType;
- }
- - (NSString *)description
- {
- return [NSString
- stringWithFormat:
- @"<%@: %p; duration: %f; delay: %f; property: %@; springDamping: %f; initialVelocity: %f; animationType: %li;>",
- NSStringFromClass([self class]),
- self,
- _duration,
- _delay,
- _property,
- _springDamping,
- _initialVelocity,
- (long)_animationType];
- }
- @end
|