Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apple/LayoutReanimation/REASwizzledUIManager.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import <RNReanimated/REAAnimationsManager.h>

@interface REASwizzledUIManager : NSObject
- (void)setIsViewTreesSynchronized:(NSNumber *)isViewTreesSynchronized;
- (instancetype)initWithUIManager:(RCTUIManager *)uiManager
withAnimationManager:(REAAnimationsManager *)animationsManager;
@end
25 changes: 24 additions & 1 deletion apple/LayoutReanimation/REASwizzledUIManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import <React/RCTUIManager.h>

@interface RCTUIManager (Reanimated)
@property (atomic) NSNumber *isViewTreesSynchronized;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It needs to be NSNumber, because I can't inject BOOL field with objc_setAssociatedObject method

@property REAAnimationsManager *animationsManager;
- (NSArray<id<RCTComponent>> *)_childrenToRemoveFromContainer:(id<RCTComponent>)container
atIndices:(NSArray<NSNumber *> *)atIndices;
Expand All @@ -24,15 +25,28 @@ - (id)animationsManager
{
return objc_getAssociatedObject(self, @selector(animationsManager));
}

@dynamic isViewTreesSynchronized;
- (void)setIsViewTreesSynchronized:(NSNumber *)isViewTreesSynchronized
{
objc_setAssociatedObject(self, @selector(isViewTreesSynchronized), isViewTreesSynchronized, OBJC_ASSOCIATION_RETAIN);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
}

- (id)isViewTreesSynchronized

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- (id)isViewTreesSynchronized
- (NSNumber *)isViewTreesSynchronized

{
return objc_getAssociatedObject(self, @selector(isViewTreesSynchronized));
}
@end

@implementation REASwizzledUIManager
@implementation REASwizzledUIManager {
NSMutableDictionary<NSNumber *, REAUIView *> *_viewRegistry;
}

- (instancetype)initWithUIManager:(RCTUIManager *)uiManager
withAnimationManager:(REAAnimationsManager *)animationsManager
{
if (self = [super init]) {
[uiManager setAnimationsManager:animationsManager];
[uiManager setIsViewTreesSynchronized:@(1)];
[self swizzleMethods];
}
return self;
Expand Down Expand Up @@ -66,6 +80,15 @@ - (void)reanimated_manageChildren:(NSNumber *)containerTag
removeAtIndices:(NSArray<NSNumber *> *)removeAtIndices
registry:(NSMutableDictionary<NSNumber *, id<RCTComponent>> *)registry
{
BOOL isUIViewRegistry = (id)registry == (id)_viewRegistry;
if (!isUIViewRegistry) {
// The `isViewTreesSynchronized` flag is necessary to prevent Reanimated from performing
// synchronous updates when there is inconsistency between the shadow tree and native tree.
// More details here: https://github.com/software-mansion/react-native-reanimated/pull/5187
[self setIsViewTreesSynchronized:@(1)];
} else {
[self setIsViewTreesSynchronized:@(0)];
}
bool isLayoutAnimationEnabled = reanimated::FeaturesConfig::isLayoutAnimationEnabled();
id<RCTComponent> container;
NSArray<id<RCTComponent>> *permanentlyRemovedChildren;
Expand Down
6 changes: 5 additions & 1 deletion apple/REANodesManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ - (void)updateView:(nonnull NSNumber *)reactTag viewName:(NSString *)viewName pr

- (void)setNeedsLayout;

- (id)isViewTreesSynchronized;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- (id)isViewTreesSynchronized;
- (NSNumber *)isViewTreesSynchronized;


@end

@interface RCTUIManager (SyncUpdates)
Expand Down Expand Up @@ -336,8 +338,10 @@ - (void)performOperations
if (strongSelf == nil) {
return;
}
BOOL canUpdateSynchronously = trySynchronously && ![strongSelf.uiManager hasEnqueuedUICommands];

auto isViewTreesSynchronized = [[strongSelf.uiManager isViewTreesSynchronized] intValue] == 1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto isViewTreesSynchronized = [[strongSelf.uiManager isViewTreesSynchronized] intValue] == 1;
auto isViewTreesSynchronized = [[strongSelf.uiManager isViewTreesSynchronized] boolValue];

BOOL canUpdateSynchronously =
trySynchronously && ![strongSelf.uiManager hasEnqueuedUICommands] && !isViewTreesSynchronized;
if (!canUpdateSynchronously) {
[syncUpdateObserver unblockUIThread];
}
Expand Down