mpiannucci / react-native-context-menu-view

Use native context menus in React Native
MIT License
664 stars 69 forks source link

Context Menu Dismissal Animation Not Properly Resetting to Original Position #109

Open Relie28 opened 9 months ago

Relie28 commented 9 months ago

Issue Description

I am encountering an issue with react-native-context-menu-view where the animation does not reset back to its original position after the context menu is dismissed. This issue is causing a significant visual glitch in my application.

Steps to Reproduce

  1. Implement react-native-context-menu-view in a component.
  2. Trigger the context menu preview and then dismiss it.
  3. Observe that the animation does not return to its original position.

Expected Behavior

The expected behavior is that after the context menu is dismissed, the animation should reset and return the component to its original position.

Actual Behavior

After dismissing the context menu, the animation remains in its final state and does not properly reset to the original position.

Visual example

https://github.com/mpiannucci/react-native-context-menu-view/assets/119743882/6fb45526-4431-4ff0-9162-bd269dd373b2

Here is a small example of what my code looks like.

<ContextMenu 
  actions={auth.public_id == item.user.public_id ? [
      { title: 'Share with...', systemIcon: 'arrowshape.turn.up.forward', identifier: 'action1' },
      { title: 'Delete', systemIcon: 'trash', identifier: 'action3', destructive: true, },
  ]
  :
  [
      { title: 'Share with...', systemIcon: 'arrowshape.turn.up.forward', identifier: 'action1' },
      { title: 'Report', destructive: true, systemIcon: 'exclamationmark.bubble', identifier: 'action2' },
  ]
}

preview={
   <View style={{ height: !item?.body?.length ? height / 1.8 : height / 1.4, width: width }}>
      <View style={{ width: '100%', flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', paddingHorizontal: 15, paddingVertical: 10, }}>
           <Image style={{ width: 35, height: 35, borderRadius: 20, backgroundColor: 'lightgray', }} source={{ uri: UseCheckImageUrl(item?.user?.image)}} />

           <Text style={{ fontFamily: 'Poppins-Medium', paddingHorizontal: 7, color: COLORS.textColor, fontSize: 13, }}>
             {item?.user?.username}
            </Text>
       </View>

       <View style={{ height: height / 1.9, width: '100%', alignItems: 'flex-start', justifyContent: 'flex-start', }}>
           <ProgressiveImage cacheKey={String(item?.public_id)} style={{ width: '100%', height: '100%', }} transition={100} cachePolicy='memory-disk' contentFit="cover" source={{ uri: UseCheckImageUrl(item?.medias?.media) }} />

            <View style={{ width: 400, paddingHorizontal: 10, paddingTop: 10, }}>
                <Text numberOfLines={2} style={{ fontFamily: 'Poppins-Light', paddingHorizontal: 7, fontSize: 13, color: COLORS.textColor, }}>
                    {item?.body}
                </Text>
            </View>
        </View>
    </View>
}

onPreviewPress={() => navigation.push('Full_Post', { postId: item?.public_id, postData: postData, Index: Index })}

onPress={(e) => {
  if (e.nativeEvent.name == 'Share with...') {
      return Share.share({
        message: Platform.OS == 'android' ? `Memory from ${item?.user?.username}, https://www.fomosocial.co/post/${item?.public_id}` : `Memory from ${item?.user?.username}`,
        url: `https://www.fomosocial.co/post/${item?.public_id}`,
      });
  } else if (e.nativeEvent.name == 'Report') {
     return reportPosts(item?.public_id);
  } else if (e.nativeEvent.name == 'Delete') {
     return deletePosts(item?.public_id);
  }
}}>
   <View style={{ height: height / 3.5, width: width / 2.15, alignDatas: 'center', overflow: 'hidden', borderRadius: Platform.OS == 'ios' ? 40 : 25, margin: 4, }}>
        <ProgressiveImage style={{ height: '100%', width: '100%', }} transition={100} cachePolicy='memory-disk' thumbnailSource={{ uri: UseCheckImageUrl(item?.medias?.media) }} source={{ uri: UseCheckImageUrl(item?.medias?.media) }} />
     </View>
</ContextMenu>

Environment

alfrol commented 2 weeks ago

I was able to fix the animation by patching the ContextMenueView.mm with the contextMenuInteraction:previewForDismissingMenuWithConfiguration:

- (UITargetedPreview *)contextMenuInteraction:(UIContextMenuInteraction *)interaction previewForDismissingMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)) {
    UIPreviewTarget* previewTarget = [[UIPreviewTarget alloc] initWithContainer:self center:self.reactSubviews.firstObject.center];
    UIPreviewParameters* previewParams = [[UIPreviewParameters alloc] init];

    if (_previewBackgroundColor != nil) {
      previewParams.backgroundColor = _previewBackgroundColor;
    }

    return [[UITargetedPreview alloc] initWithView:self.reactSubviews.firstObject
                                        parameters:previewParams
                                            target:previewTarget];
}

Before:

https://github.com/user-attachments/assets/ebd62997-1e42-420f-9946-da72149d5dd2

After:

https://github.com/user-attachments/assets/b7bb800e-f4f5-4f1f-a1b9-deb07e70899c

@mpiannucci I noticed that this method (along with contextMenuInteraction:previewForHighlightingMenuWithConfiguration: which is already implemented in the library) is deprecated since iOS 17.0. It might be worth implementing the new methods instead: