123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- /*
- * 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 <React/RCTPropsAnimatedNode.h>
- #import <React/RCTLog.h>
- #import <React/RCTSurfacePresenterStub.h>
- #import <React/RCTUIManager.h>
- #import <React/RCTAnimationUtils.h>
- #import <React/RCTStyleAnimatedNode.h>
- #import <React/RCTValueAnimatedNode.h>
- @implementation RCTPropsAnimatedNode
- {
- NSNumber *_connectedViewTag;
- NSNumber *_rootTag;
- NSString *_connectedViewName;
- __weak RCTBridge *_bridge;
- NSMutableDictionary<NSString *, NSObject *> *_propsDictionary; // TODO: use RawProps or folly::dynamic directly
- BOOL _managedByFabric;
- }
- - (instancetype)initWithTag:(NSNumber *)tag
- config:(NSDictionary<NSString *, id> *)config
- {
- if (self = [super initWithTag:tag config:config]) {
- _propsDictionary = [NSMutableDictionary new];
- }
- return self;
- }
- - (BOOL)isManagedByFabric
- {
- return _managedByFabric;
- }
- - (void)connectToView:(NSNumber *)viewTag
- viewName:(NSString *)viewName
- bridge:(RCTBridge *)bridge
- {
- _bridge = bridge;
- _connectedViewTag = viewTag;
- _connectedViewName = viewName;
- _managedByFabric = RCTUIManagerTypeForTagIsFabric(viewTag);
- _rootTag = nil;
- }
- - (void)disconnectFromView:(NSNumber *)viewTag
- {
- _bridge = nil;
- _connectedViewTag = nil;
- _connectedViewName = nil;
- _managedByFabric = NO;
- _rootTag = nil;
- }
- - (void)updateView
- {
- if (_managedByFabric) {
- [_bridge.surfacePresenter synchronouslyUpdateViewOnUIThread:_connectedViewTag
- props:_propsDictionary];
- } else {
- [_bridge.uiManager synchronouslyUpdateViewOnUIThread:_connectedViewTag
- viewName:_connectedViewName
- props:_propsDictionary];
- }
- }
- - (void)restoreDefaultValues
- {
- // Restore the default value for all props that were modified by this node.
- for (NSString *key in _propsDictionary.allKeys) {
- _propsDictionary[key] = [NSNull null];
- }
- if (_propsDictionary.count) {
- [self updateView];
- }
- }
- - (NSString *)propertyNameForParentTag:(NSNumber *)parentTag
- {
- __block NSString *propertyName;
- [self.config[@"props"] enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull property, NSNumber *_Nonnull tag, BOOL *_Nonnull stop) {
- if ([tag isEqualToNumber:parentTag]) {
- propertyName = property;
- *stop = YES;
- }
- }];
- return propertyName;
- }
- - (void)performUpdate
- {
- [super performUpdate];
- // Since we are updating nodes after detaching them from views there is a time where it's
- // possible that the view was disconnected and still receive an update, this is normal and we can
- // simply skip that update.
- if (!_connectedViewTag) {
- return;
- }
- for (NSNumber *parentTag in self.parentNodes.keyEnumerator) {
- RCTAnimatedNode *parentNode = [self.parentNodes objectForKey:parentTag];
- if ([parentNode isKindOfClass:[RCTStyleAnimatedNode class]]) {
- [self->_propsDictionary addEntriesFromDictionary:[(RCTStyleAnimatedNode *)parentNode propsDictionary]];
- } else if ([parentNode isKindOfClass:[RCTValueAnimatedNode class]]) {
- NSString *property = [self propertyNameForParentTag:parentTag];
- id animatedObject = [(RCTValueAnimatedNode *)parentNode animatedObject];
- if (animatedObject) {
- self->_propsDictionary[property] = animatedObject;
- } else {
- CGFloat value = [(RCTValueAnimatedNode *)parentNode value];
- self->_propsDictionary[property] = @(value);
- }
- }
- }
- if (_propsDictionary.count) {
- [self updateView];
- }
- }
- @end
|